vue h render function All In One
vue h render function All In One
vue h 渲染函数 All In One
h()
函数是一个用于创建 VNode 的实用程序。
也许可以更准确地将其命名为 createVNode()
,但由于频繁使用和简洁,它被称为 h()
。
它接受三个参数:tag
, props
, children
{String | Object | Function}
tag{Object}
props 可选,{String | Array | Object}
children 可选,
如果没有 prop
,那么通常可以将 children
作为第二个参数传入。
如果会产生歧义,可以将 null
作为第二个参数传入,将 children 作为第三个参数传入。
// @returns {VNode}
h(
// {String | Object | Function} tag
// 一个 HTML 标签名、一个组件、一个异步组件、或 一个函数式组件。
//
// 必需的。
'div',
// {Object} props
// 与 attribute、prop 和事件相对应的对象。
// 这会在模板中用到。
//
// 可选的。
{},
// {String | Array | Object} children
// 子 VNodes, 使用 `h()` 构建,
// 或使用字符串获取 "文本 VNode" 或者
// 有插槽的对象。
//
// 可选的。
[
'Some text comes first.',
h('h1', 'A headline'),
h(MyComponent, {
someProp: 'foobar'
})
]
)
vue 2.x
Vue.component('custom-btn', {
data() {
return {
text: 'Click me',
};
},
methods: {
handleClick() {
console.log('clicked 👻');
},
},
render(h) {
return h('button', {
attrs: {
class: 'btn-primary'
},
on: {
click: this.handleClick,
},
}, this.text);
},
});
https://cn.vuejs.org/v2/guide/render-function.html#createElement-参数
JSX
const h = this.$createElement;
将 h 作为 createElement 的别名是 Vue 生态系统中的一个通用惯例,实际上也是 JSX 所要求的。
从 Vue 的 Babel 插件的 3.4.0 版本开始,我们会在以 ES2015 语法声明的含有 JSX 的任何方法和 getter 中 (不是函数或箭头函数中) 自动注入 const h = this.$createElement,这样你就可以去掉 (h) 参数了。
对于更早版本的插件,如果 h 在当前作用域中不可用,应用会抛错。
https://cn.vuejs.org/v2/guide/render-function.html#JSX
vue 3.x
const { createApp, h } = Vue
const app = createApp({})
/** 递归地从子节点获取文本 */
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() {
// 从 children 的文本内容中创建短横线分隔 (kebab-case) id。
const headingId = getChildrenTextContent(this.$slots.default())
.toLowerCase()
.replace(/\W+/g, '-') // 用短横线替换非单词字符
.replace(/(^-|-$)/g, '') // 删除前后短横线
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/render-function.html#h-参数
vue 3 & render function
https://vuejs.org/guide/extras/render-function.html
https://staging-cn.vuejs.org/guide/extras/render-function.html
demo
import Vue from "vue";
// 全局注册组件
Vue.component("render-function-btn", {
data() {
return {
text: "Click me",
count: 0
};
},
methods: {
handleClick() {
if (this.count === 0) {
this.text = "clicked 🚀";
}
this.count++;
console.log("clicked 🚀");
}
},
render(h) {
// h 渲染函数 (tag, props, children)
return h("div", {}, [
h("p", null, `Vue.component & h 渲染函数`),
h(
"button",
{
attrs: {
class: "btn-primary"
},
on: {
click: this.handleClick
}
},
`👻 ${this.text} = ${this.count}`
)
]);
// return h(
// "button",
// {
// attrs: {
// class: "btn-primary"
// },
// on: {
// click: this.handleClick
// }
// },
// `👻 ${this.text} = ${this.count}`
// );
}
});
https://zyszys.github.io/vue-patterns-cn/patterns/#渲染函数
refs
©xgqfrms 2012-2020
www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!
原创文章,版权所有©️xgqfrms, 禁止转载 🈲️,侵权必究⚠️!
本文首发于博客园,作者:xgqfrms,原文链接:https://www.cnblogs.com/xgqfrms/p/16355452.html
未经授权禁止转载,违者必究!