简体中文
| Web | 微信小程序 | Android | iOS | HarmonyOS | |
|---|---|---|---|---|---|
| h() | 4.0 | x | 3.99 | 4.11 | 4.61 |
| mergeProps() | 4.0 | - | 4.0 | 4.11 | 4.61 |
| cloneVNode() | 4.0 | - | 4.0 | x | x |
| isVNode() | 4.0 | - | √ | 4.11 | 4.61 |
| resolveComponent() | 4.0 | x | √ | 4.11 | 4.61 |
| resolveDirective() | - | - | - | - | - |
| withDirectives() | 4.0 | 4.41 | x | 4.11 | 4.61 |
| withModifiers() | 4.0 | - | √ | 4.11 | 4.61 |
创建虚拟 DOM 节点 (vnode)。
详细信息
第一个参数既可以是一个字符串 (用于原生元素) 也可以是一个 Vue 组件定义。第二个参数是要传递的 prop,第三个参数是子节点。
当创建一个组件的 vnode 时,子节点必须以插槽函数进行传递。如果组件只有默认槽,可以使用单个插槽函数进行传递。否则,必须以插槽函数的对象形式来传递。
为了方便阅读,当子节点不是插槽对象时,可以省略 prop 参数。
示例 详情
组合式 API
选项式 API
<script setup lang="uts">
import CompForHFunction from '@/components/CompForHFunction.uvue'
import CompForHFunctionWithSlot from '@/components/CompForHFunctionWithSlot.uvue'
import Foo from './Foo.uvue'
const msg = ref('default msg')
const list = ref(['a','b'])
// 故意外部声明为UTSJSONObject
const msgProps = { class: 'mt-10 msg', style: { color: 'blue' } }
// #ifdef APP-ANDROID
const render = computed(():VNode => {
// #endif
// #ifndef APP-ANDROID
const render = ():VNode => {
// #endif
const textList: VNode[] = []
list.value.forEach((item) => {
textList.push(h('text', { class: 'text-item' }, item))
})
return h('view', { class: 'page' }, [
h(CompForHFunctionWithSlot, {}, () : VNode[] => [h('text', { class: 'comp-slot' }, 'component slot')]),
h(CompForHFunction, { msg: msg.value }),
h('text', msgProps, msg.value),
h(Foo, null, {
header: (): VNode[] => [h('text', { id: "header" }, 'header')],
footer: (): VNode[] => [h('text', { id: "footer" }, 'footer')]
}),
h('view', null, textList),
h(
'button',
{
class: 'mt-10 btn',
type: 'primary',
onClick: () => {
msg.value = 'new msg'
list.value.push('c')
}
},
'click'
)
])
}
// #ifdef APP-ANDROID
)
// #endif
</script>
<template><render /></template>
<style>
.btn {
color: red;
}
</style>
合并多个 props 对象,用于处理含有特定的 props 参数的情况。
详细信息
mergeProps() 支持以下特定 props 参数的处理,将它们合并成一个对象。
示例 详情
组合式 API
选项式 API
<template>
<view class="page">
<view class="mb-10 flex flex-row justify-between">
<text>merged class</text>
<text id="merged-class">{{mergedProps['class']}}</text>
</view>
<button class="mb-10" id="trigger-merged-click" @click="triggerMergedClick">trigger merged onClick</button>
<view>
<text class="mb-10">prop function result list</text>
<text class="click-res" v-for="(item, index) in propFnResList" :key="index">{{item}}</text>
</view>
</view>
</template>
<script setup lang="uts">
type PropFn = () => string
const propA = {
class: 'foo',
onClick: () : string => 'propA click res'
}
const propB = {
class: { bar: true },
onClick: () : string => 'propB click res'
}
const mergedProps = ref({})
const propFnResList = ref<string[]>([])
mergedProps.value = mergeProps(propA, propB)
const triggerMergedClick = () => {
(mergedProps.value['onClick'] as PropFn[]).forEach(fn => { propFnResList.value.push(fn()) })
}
</script>
克隆一个 vnode。
详细信息
返回一个克隆的 vnode,可在原有基础上添加一些额外的 prop。
Vnode 被认为是一旦创建就不能修改的,你不应该修改已创建的 vnode 的 prop,而应该附带不同的/额外的 prop 来克隆它。
Vnode 具有特殊的内部属性,因此克隆它并不像 object spread 一样简单。cloneVNode() 处理了大部分这样的内部逻辑。
示例 详情
组合式 API
选项式 API
<script setup lang="uts">
defineOptions({
render() : VNode {
const originalVNode = h('view', { class: 'original' }, [
h('text', {}, 'Hello World'),
])
const clonedVNode = cloneVNode(originalVNode, { class: 'cloned' })
return h('view', { class: 'flex flex-col' }, [originalVNode, clonedVNode])
}
})
</script>
<style>
.original {
background-color: #ff0000;
}
.cloned {
background-color: #00ff00;
}
</style>
判断一个值是否为 vnode 类型。
组合式 API
选项式 API
<template>
<view class="page">
<view class="mb-10 flex flex-row justify-between">
<text>isVNode VNode:</text>
<text id="is-vnode-vnode">{{ isVNodeVNode }}</text>
</view>
<view class="mb-10 flex flex-row justify-between">
<text>isVNode string:</text>
<text id="is-vnode-string">{{ isVNodeString }}</text>
</view>
</view>
</template>
<script setup lang="uts">
const isVNodeVNode = ref(false)
const isVNodeString = ref(false)
const vnode = h('text', {}, 'Hello World')
isVNodeVNode.value = isVNode(vnode)
isVNodeString.value = isVNode('abc')
</script>
按名称手动解析已注册的组件。
详细信息
备注:如果你可以直接引入组件就不需使用此方法。
为了能从正确的组件上下文进行解析,resolveComponent() 必须在 setup() 或渲染函数内调用。
如果组件未找到,会抛出一个运行时警告,并返回组件名字符串。
示例 详情
组合式 API
选项式 API
<script setup lang="uts">
defineOptions({
render() : VNode {
const CompForAppComponent = resolveComponent('CompForAppComponent')
return h(CompForAppComponent)
}
})
</script>
用于给 vnode 增加自定义指令。
详细信息
用自定义指令包装一个现有的 vnode。第二个参数是自定义指令数组。每个自定义指令也可以表示为 [Directive, value, argument, modifiers] 形式的数组。如果不需要,可以省略数组的尾元素。
示例 详情
组合式 API
选项式 API
<script setup lang="ts">
defineOptions({
data() {
return {
isMounted: false
}
},
render() : VNode {
const instance = getCurrentInstance()!.proxy!
const customDirective = {
mounted(el : UniElement, binding : DirectiveBinding, vnode : VNode, prevVNode: VNode | null) {
console.log(el, binding, vnode, prevVNode)
instance.$data['isMounted'] = true
}
} as Directive
return h('view', { class: 'page' }, [
withDirectives(h('text', 'Hello World'), [[customDirective]]),
h('view', { class: 'mt-10 flex flex-row justify-between' }, [
h('text', {}, `isMounted:`),
h('text', { id: 'is-mounted' }, `${instance.$data['isMounted']}`),
])
])
}
})
</script>
用于向事件处理函数添加内置 v-on 修饰符。