// @returns {VNode}
h(
// {String | Object | Function | null} tag
// 一个 HTML 标签名、一个组件、一个异步组件,或者 null。
// 使用 null 将会渲染一个注释。
//
// 必需的。
'div',
// {Object} props
// 与 attribute、prop 和事件相对应的对象。
// 我们会在模板中使用。
//
// 可选的。
{},
// {String | Array | Object} children
// 子 VNodes, 使用 `h()` 构建,
// 或使用字符串获取 "文本 Vnode" 或者
// 有插槽的对象。
//
// 可选的。
[
'Some text comes first.',
h('h1', 'A headline'),
h(MyComponent, {
someProp: 'foobar'
})
]
)
接收三个参数:type,props 和 children
在 2.x 中,render 函数会自动接收 h 函数 (它是 createElement 的传统别名) 作为参数:
// Vue 2 渲染函数示例
export default {
render(h) {
return h('div')
}
}
在 3.x 中,h 现在是全局导入的,而不是作为参数自动传递。
// Vue 3 渲染函数示例
import { h } from 'vue'
export default {
render() {
return h('div')
}
}
import { h, reactive } from 'vue'
export default {
setup(props, { slots, attrs, emit }) {
const state = reactive({
count: 0
})
function increment() {
state.count++
}
// 返回渲染函数
return () =>
h(
'div',
{
onClick: increment
},
state.count
)
}
}
const { createApp, h } = Vue
const app = createApp({})
/** Recursively get text from children nodes */
function getChildrenTextContent(children) {
return children
.map(node => {
return typeof node.children === 'string'
? node.children
: Array.isArray(node.children)
? getChildrenTextContent(node.children)
: ''
})
.join('')
}
app.component('anchored-heading', {
render() {
// create kebab-case id from the text contents of the children
const headingId = getChildrenTextContent(this.$slots.default())
.toLowerCase()
.replace(/\W+/g, '-') // replace non-word characters with dash
.replace(/(^-|-$)/g, '') // remove leading and trailing dashes
return h('h' + this.level, [
h(
'a',
{
name: headingId,
href: '#' + headingId
},
this.$slots.default()
)
])
},
props: {
level: {
type: Number,
required: true
}
}
})
https://v3.cn.vuejs.org/guide/migration/render-function-api.html
https://v3.cn.vuejs.org/api/global-api.html#h
https://v3.cn.vuejs.org/guide/render-function.html#%E8%99%9A%E6%8B%9F-dom-%E6%A0%91