render 函数的作用
简单的说,在vue中使用模板HTML语法组建页面,使用render函数可以用js语言来构建DOM
因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程。
当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具。官网上给他起了个名字叫createElement。还有约定的简写叫h,
栗子:根据 data 中 level 的值,用不同标题标签显示文本:
<div id="app">
<child-component :level="level">
哆啦A梦
</child-component>
</div>
Vue.component('child-component', {
props: ['level'],
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>`
})
var app = new Vue({
el: '#app',
data: {
level: 1
}
})
将 level 的值改成 1,会渲染 template 中的 h1 标签。
实际开发中可能会把 template 写得巨长;使用 render 函数来实现上面的 demo:
<div id="app">
<child :level="level">
哆啦A梦
</child>
</div>
<script>
// 使用render函数进行定义组件
Vue.component('child', {
render: function (createElement) {
return createElement('h' + this.level,
this.$slots.default);
},
props: ['level']
})
var app = new Vue({
el: '#app',
data: {
level: 1
}
})
</script>
渲染效果与上面使用 template 一致。
使用 render函数 比 template 要简洁很多。
render函数用法
- render函数可以接收 createElement 作为参数,并且必须是 createElement;
- createElement 也是一个函数;
- createElement 可以传三个参数(上面只传了两个);
第一个参数必需,可以是 String / Object / Function 类型;
第二个参数可选,只能是 Object 类型;
第三个参数可选,可以是 String / Array 类型。
createElement 的第一个参数
- 第一个参数必选
- 可以是string - html标签
- 可以是object -- 一个含有数据选项的对象
- 可以是function ---方法返回含有数据选项的对象
<body>
<div id="app">
<child></child>
</div>
<script>
Vue.component('child', {
render: function (createElement) {
// 1. 传 String
return createElement('h1') // 创建一个 HTML 标签
// 2. 传 Object
return createElement({ // 创建一个含有数据选项的对象
template: '<h1>你好</h1>'
})
// 3. 传 Function(函数最终要 return 对象,所以本质上还是传的对象)
return createElement(function () {
return {
template: '<h1>你好</h1>'
}
}()) // 函数要调用一下,否则不起效果
}
})
var app = new Vue({
el: '#app',
data: {
}
})
</script>
createElement 的第二个参数
- 第二个参数可选,只能是 Object 类型,Object 中可以设置元素的一些属性。
<div id="app">
<child></child>
</div>
<script>
Vue.component('child', {
//第二个参数可选,第二个参数是数据对象
render: function (createElement) {
return createElement({
template: '<div>花间提壶方大厨</div>'
}, {
class: {
foo: true,
baz: false
},
style: {
color: 'red',
fontSize: '16px'
},
//正常的 html 特性
attrs: {
id: "foo",
src: 'http://www.baidu.com'
}
})
}
})
var app = new Vue({
el: '#app',
})
</script>
createElement 的第三个参数
- 第三个参数可选, 可以是 String | Array ---代表子节点
<div id="app">
<child></child>
</div>
<script>
Vue.component('child', {
//第三个参数可选, 可以是 String | Array ---代表子节点
render: function (createElement) {
return createElement('div', [
createElement('h2', '我是h2标题'),
createElement('h5', '我是h5标题')
])
}
})
var app = new Vue({
el: '#app',
})
</script>