前言:
- 在绝大多数情况下,Vue 推荐使用模板语法来创建应用。然而在某些使用场景下,我们真的需要用到 JavaScript 完全的编程能力。这时渲染函数就派上用场了。
- 渲染函数 (h()), HyperScript(). 主要用于处理模板中较难处理的纯 JavaScript 逻辑视图的函数, 把虚拟 DOM 转化成真实 DOM
h 函数工作流程
- h 函数( createNodeDescription )
- 创建节点函数
- vNode(虚拟节点)
- 多个vNode组成虚拟DOM树
h 函数处理过程
- 模板提供: 组件(模板, 属性, 方法, 指令...)
- 编译优化: 编译模板和属性 (AST树 -> 优化) -> VNode (虚拟节点; 虚拟DOM节点是对真实DOM节点的描述)
- 更新对比 (AST对象的对比 -> 打补丁(patch) -> 通知更新)
h 函数的使用
参数:
- 第一个参数: 元素/组件(tag)
- 第二个参数: {} (options)
- 第三个参数: children (如果没有options, 则children为第二个参数)
使用注意:
- 虚拟节点的引用不能重复 (多个child, 不要使用同一个虚拟节点)
- 使用 resolveComponent(componentName) 在h函数中使用全局组件
- 局部注册了App, 等价于全局注册 components: { App }
h 函数的高级用法
h 函数中使用 v 自带指令
h 函数中的没有像模板一样的自带指令, 需要用户自己实现这样的逻辑
- v-if: if (this.isOpened) { retrun h('xxx') } else { return h('xxx') }
- v-show: style property
- v-for: (map, filter, ...)
- v-model: value event onUpdate:value
- v-on:
-
- on: {} (vue2.0)
- onClick (vue3.0); Vue3中修饰符用大驼峰的方式来写 (详细参考render函数的一章)
h 函数的自定义指令 (resolveDirective & withDirectives)
// h函数的自定义指令 (resolveDirective & withDirectives)
const pin = resolveDirective('pin');
return withDirectives(h('div'), [
[pin, 200, 'top', { animate: true }]
]);
h 函数中使用插槽 (VNode[])
- 默认插槽: h('div', { class: 'title' }, this.$slots.default())
- 具名插槽: h('div', { class: 'title' }, this.$slots.left())
- 默认内容的插槽 h('div', { class: 'title' }, this.$slots.content({ content: 'xxx' }))
h 函数中使用动态组件
resolveDynamicComponent
h 函数配合 jsx 使用
yarn add @vue/babel-plugin-jsx -D- babel config 配置 plugins