render函数在vue中的使用也是非常多的,使用恰当可以让我们的代码看起来更加清晰明了,接下来用官方的一个小例子来看看render的基本用法
<div id="app">
<anchored-heading :level="1">Hello world!</anchored-heading>
<anchored-heading :level="2">Hello world!</anchored-heading>
<anchored-heading :level="3">Hello world!</anchored-heading>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
Vue.component('anchored-heading', {
template: `
<div>
<h1 v-if="level === 1">
<slot></slot>
</h1>
<h2 v-if="level === 2">
<slot></slot>
</h2>
<h3 v-if="level === 3">
<slot></slot>
</h3>
</div>
`,
props: {
level: {
type: Number,
required: true
}
}
});
new Vue({
el: '#app'
})
</script>
结果如下:这是我们用之前的模板组件来实现的,可以看出模板中slot元素重复的出现,render函数可以为我们降低代码的冗余
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 子节点数组
)
},
props: {
level: {
type: Number,
required: true
}
}
});
我们只改变anchored-heading这个模板内容,这样就一目了然啦!
简单的了解一下render函数的使用,接下来我们再去详细的看看
render函数接收一个createElement函数作为参数,createElement这个函数看着怎么这么眼熟呢,这倒是让我想起了document.createElement(),document.createElement()返回一个DOM节点,而render函数中的createElement函数返回的并不是一个实际的DOM元素,别问我为什么,因为官网这么说的-.-
我们再把用createElement创建的虚拟DOM和document.createElement创建的DOM节点分别打印出来:
这样就很直观了,emmmm这个VNode看起来更像是一个对象...
createElement参数
createElement接收三个参数,第一个必传参数为一个标签名,或者是组件名,第二个参数为将要创建这个模板的数据对象,第三个参数为将要创建的这个模板的子虚拟节点
Vue.component('test-render', {
render(createElement) {
return createElement(
//标签名
'div',
//将要创建模板的数据
{
'class': 'test',
style: {
background: 'yellow'
}
},
//子虚拟dom
[
Array.apply(null, {length: 5}).map(()=> {
return createElement('p', '我是p标签')
})
]
)
}
});
结果如下:
这里要注意的一点是VNode必须唯一,虽然我试了相同的好像也可以使用,不过还是按照官方写法来,避免出现莫名其妙的bug。如果有知道底层的话不妨说说,在这里先谢谢各位dalao了!