一般情况下,在vue中,我们定义组件时,都使用template(模板)来创建HTML,但如果我们的HTML需要使用javaScript来生成的话,应该怎么办?
1、render函数的使用意义
渲染节点
2、示例
官方文档给我们提供了一个很好理解的例子:
我们需要创建一个这样的组件:
<anchored-heading :level="1">Hello world!</anchored-heading>
当level传入1时,渲染出来的html内容就是<h1>Hello world</h1>,传入2时,渲染出来的html内容就是<h2>Hello world</h2>……
很明显我们想渲染的节点标签不是写死在模板里的。
使用render来实现该组件:
Vue.component('anchored-heading', {
render: function (createElement) {
return createElement(
'h' + this.level, // 标签名称
this.$slots.default // 由子节点构成的数组
)
},
props: {
level: {
type: Number,
required: true
}
}
})
render是一个渲染函数,返回值是DOM节点。
示例代码第三行:我们在createElement()这个函数里传了两个参数,第一个参数是节点名称,跟this.level挂钩,this.level是1,节点名称就是<h1>,是2节点名称就是<h2>,第二个参数是节点下的子节点,$slots.defult的含义可查询官网api中的实例属性: https://vuefe.cn/v2/api/#vm-slots,它得到的是所有没有被包含在具名slot中的节点。由此render函数渲染出新节点。
附createElement函数的定义:
// @returns {VNode}
createElement(
//第一个参数: {String | Object | Function}.(必填项)
// 一个 HTML 标签,组件设置,或一个函数
// 必须 Return 上述其中一个,例如"div"
// 第二个参数:{Object}
// 一个对应属性的数据对象.(可选项)
//例如,样式属性:{style: {color: 'red',fontSize: '20px'}}
//第三个参数: {String | Array}
// 子节点(VNodes).(可选项)
//例如:
// [
// createElement('h1', 'hello world'),
//"<p>哈哈哈</p>"
//]
//这里我们可以传入数组,也可以直接传入一段节点中的文本内容(String),实际上节点内的文本内容也属于它的子节点。
在render函数中我们可以直接使用原生js来实现v-if、v-for等指令。