Vue中渲染函数的使用
- vue中的渲染函数:
- 1.
template
- 2.
render函数
- 3.
jsx -> js extension
(jsx
也是编译成render函数
,可编程能力更强
)
- 1.
1. render函数
1.1. 认识h函数
- 1.1.1. Vue推荐在绝大多数情况下使用模板来创建HTML,一些特殊的场景,真的需要javaScript的完全编程的能力,
这个时候可以使用渲染函数,它比模板更接近编译器。 - 1.1.2.
VNode
和VDom
的概念Vue在生成
真实DOM
之前,会将我们的节点转换成VNode, 而VNode组合在一起形成一棵树结构
,就是虚拟DOM(VDOM)
;事实上,之前编写的
template中的HTML
最终也是使用渲染函数生成对应的VNode
;如果想重复利用
JavaScript的编程能力
,可以编写createVNode函数,生成对应的VNode
;Vue底层渲染流程如下图:
<!-- HTML模板 --> <!-- h函数 --> <!-- 虚拟节点VNode --> <!-- 真实DOM --> <template> <div> createVNode() VNode 真实DOM <h2></h2> createVNode() ↙ ↘ ↙ ↘ <p></p> createVNode() VNode VNode h2 p </div> </template>
- 1.1.1. Vue推荐在绝大多数情况下使用模板来创建HTML,一些特殊的场景,真的需要javaScript的完全编程的能力,
1.2. 使用h函数
- h() 函数是一个用于创建vnode的一个函数;
- 其实更准确的命名是createVNode()函数,但是为了简便在Vue将之简化为h()函数(本质上是createVNode()函数)
2. h()的使用
- h()函数接收三个参数:tag, props, children
{ String | Object | Function } tag { Object } props { String | Array | Object } children 一个HTML标签、一个组件、一个异步组件、或 与attribute、prop 和事件相对应的对象 子 VNodes, 使用`h()` 构建 一个函数式组件 会在模板中使用 使用字符串获取 `文本 VNode`或`有插槽的对象` 必需的 可选的 可选的 例如:'div' { } [ 'some text comes first', h('h1', null, '哈哈哈哈'), h(myComponent, {someProp: 'fooBar'}) ]
- 注意事项:
- 如果没有props, 通常可以将children作为第二个参数传入;
- 如果会产生歧义,可以将null作为第二个参数传入,将children作为第三个参数传入;
- HTML转成VNode的调用案例:
<div class="abc" title='内容'> h2 p </div> // 转成VNode: createVNode('div', { class: 'abc', title: '内容' }, [ createVNode('h2', null, '我是标题'), createVNode('p', { }, '我是内容') ])
- createVNode函数的调用如下图;
3. render函数和h函数的区分
流程:render函数是放在对应的组件选项里面的,当渲染组件的时候,会调用render函数,一旦调用就会返回的VNode,为了去创建一系列的VNode, 所以会调用h函数并渲染成HTML
区分:render函数是写到组件里面的,而h函数(createVNode函数)才是真正去创建VNode的
-
- render函数使用
-
Options API
的用法,使用render函数选项
- 代码如下:
<script> import { h } from 'vue' import Home from './Home.vue' export default { data () { return { counter: 0 } }, render () { console.log('this===', this); return h('div', { class: 'app' } , [ h('h2', { class: 'title' }, `当前计数:${ this.counter }`), h('button', { onClick: this.increment }, '+1'), h('button', { onClick: this.decrement }, '-1'), // 在render函数中,引入其他组件不需要注册(components), 在template模板中需要注册 h(Home) ]) }, methods: { increment () { this.counter++ }, decrement() { this.counter-- } } } </script>
-
Composition API
的用法
- 2.1.
setup函数
的使用,- 关键点:
setup()
中返回一个函数,函数中返回VNode setup函数
默认返回一个对象=>
return { counter, increment, decrement }
setup函数
中使用render函数
,不要返回对象,setup本身需要是返回一个函数类型, 箭头函数中再去返回VNode
- 代码如如下:
<script> import { h, ref } from 'vue' import Home from './Home.vue' export default { setup () { const counter = ref(0) const increment = () => { counter.value++ } const decrement = () => { counter.value-- } // setup函数默认返回一个对象 => return { counter, increment, decrement } // setup函数中使用render函数,不要返回对象,返回一个函数, 箭头函数中再去返回VNode return () => { return h('div', {className: 'app' }, [ h('h2', { className: 'title' }, `当前计数: ${ counter.value }`), h('button', { onClick: increment }, '+1'), h('button', { onClick: decrement} , '-1'), h(Home) ]) } // return () => h('div', {className: 'app' }, [ // h('h2', { className: 'title' }, `当前计数: ${ counter.value }`), // h('button', { onClick: increment }, '+1'), // h('button', { onClick: decrement} , '-1'), // h(Home) // ]) } } </script>
- 关键点:
- 2.2.
setup语法糖
的使用- 在setup中义render函数
- 在template模板中使用render标签
- 代码如下;
<template> <render/> </template> <script setup> import { ref, h } from 'vue' import Home from './Home.vue' const counter = ref(0) const increment = () => { counter.value++ } const decrement = () => { counter.value-- } // 使用render函数,是为了使用js的方式去编写代码,基本上很少使用 // 如果依然想使用JS的方式编写,可以使用JSX语法,JSX本质会转化成render函数 // JSX的优点:1. 快速的编写元素的结构 2. 完全可以利用JS编程能力 const render = () => h('div', {className: 'app' }, [ h('h2', { className: 'title' }, `当前计数: ${ counter.value }`), h('button', { onClick: increment }, '+1'), h('button', { onClick: decrement} , '-1'), h(Home) ]) </script>
-
- render函数的使用推荐
- 使用render函数,是为了使用js的方式去编写代码,
基本上很少使用
- 如果依然想使用JS的方式编写,可以使用JSX语法,JSX本质会转化成render函数
JSX的优点
:-
- 快速的编写元素的结构
-
- 完全可以利用JS编程能力
-