前言:关于什么是渲染函数,什么是h()这些东西我就不说了,以及h函数里面的各种参数,在Vue官网中都有详细解释,这篇文章主要针对Vue3渲染函数中的一些api结合自己的开发经验进行叙述。
mergeProps()
主要合并class,style,事件监听(多个同名的事件监听器将被合并到一个数组) 顾名思义,合并props,为什么要合并props?当然是因为小孩子才做选择,成年人都要!
import { mergeProps } from 'vue'
const one = {
class: 'foo',
onClick: handlerA
}
const two = {
class: { bar: true },
onClick: handlerB
}
const merged = mergeProps(one, two)
// 合并后 ↓
// 拥有了两个class的样式,一个onClick可以做两件事
/**
{
class: 'foo bar',
onClick: [handlerA, handlerB]
}
*/
cloneVNode()
顾名思义,克隆虚拟节点返回一个克隆的 vnode,可在原有基础上添加一些额外的 prop。
// 类型定义:
function cloneVNode(vnode: VNode, extraProps?: object): VNode
// 示例:
import { h, cloneVNode } from 'vue'
const original = h('div')
const cloned = cloneVNode(original, { id: 'foo' }) // 克隆一个有额外prop的节点
isVNode()
判断一个值是否为 vnode 类型,返回一个Boolean
resolveComponent()
按名称手动解析已注册的组件。
此方法只针对无法通过引入vue文件
的方法来获取组件的情况,什么时候我们没办法通过引入vue文件的方法获取到组件呢?请看如下示例:
// 全局注册组件
Vue.component('GlobalComponent', {
template: '<div>Global Component</div>'
})
// 渲染函数
function render() {
const component = resolveComponent('GlobalComponent')
return h(component)
}
在上述示例中,我们在全局注册了一个组件 GlobalComponent
,但我们无法通过直接导入的方式在渲染函数中使用它。因此,我们使用 resolveComponent('GlobalComponent')
来获取组件定义,并将其传递给 h()
函数进行渲染。
备注:如果你可以直接引入组件就不需使用此方法。
为了能从正确的组件上下文进行解析,resolveComponent()
必须在setup()
或渲染函数内调用。
如果组件未找到,会抛出一个运行时警告,并返回组件名字符串。
resolveDirective()
按名称手动解析已注册的指令。
function resolveDirective(name: string): Directive | undefined
备注:如果你可以直接引入组件就不需使用此方法。
以下是无法通过导入指令的方式进行手动获取指令的情况:
import { h, withDirectives, resolveDirective } from 'vue'
// 自定义指令的名称注册
Vue.directive('my-directive', {
mounted(el, binding) {
// 指令逻辑
},
updated(el, binding) {
// 指令逻辑
}
})
// 渲染函数
function render() {
const directive = resolveDirective('my-directive')
}
在上述示例中,我们通过名称注册了一个自定义指令 my-directive
,但无法通过直接导入的方式在渲染函数中使用它。为了解决这个问题,我们使用 resolveDirective('my-directive')
来获取指令定义
为了能从正确的组件上下文进行解析,resolveDirective()
必须在setup()
或渲染函数内调用。
如果指令没有找到,会抛出一个运行时警告,并返回 undefined
。
withDirectives()
用于给 vnode 增加自定义指令
类型:
function withDirectives(
vnode: VNode,
directives: DirectiveArguments
): VNode
// [Directive, value, argument, modifiers]
type DirectiveArguments = Array<
| [Directive]
| [Directive, any]
| [Directive, any, string]
| [Directive, any, string, DirectiveModifiers]
>
用自定义指令包装一个现有的 vnode。第二个参数是自定义指令数组。每个自定义指令也可以表示为 [Directive, value, argument, modifiers]
形式的数组。如果不需要,可以省略数组的尾元素。
示例:
// <div v-pin:top.animate="200"></div>
const vnode = withDirectives(h('div'), [ [pin, 200, 'top', { animate: true }] ])
withModifiers()
用于向事件处理函数添加
内置
v-on
修饰符
类型:
function withModifiers(fn: Function, modifiers: string[]): Function
示例:
const vnode = h('button', {
// 等价于 v-on:click.stop.prevent
onClick: withModifiers(() => {
// ...
}, ['stop', 'prevent']) })
一些要点
v-model
指令扩展为 modelValue
和 onUpdate:modelValue
诸如 <KeepAlive>
、<Transition>
、<TransitionGroup>
、<Teleport>
和 <Suspense>
等内置组件在渲染函数中必须导入才能使用
渲染函数中v-if:
// 判断必须是响应式依赖
h('div', [ok.value ? h('div', 'yes') : h('span', 'no')])