render函数概述
除了 <template>
,还可以使用 render
函数去让Vue在页面中显示内容。
当将一个函数传递给Vue实例的 render
属性时,该函数会传入一个 createElement
函数,并通过它来指定需要在页面上显示的HTML。
示例:
<script>
new Vue({
el: '#app',
render(createElement){
return createElement('h1', 'hello world!');
}
});
</script>
createElement
接受三个参数:将要生成的元素的标签名称、包含配置信息的数据对象和一个子节点或是包含子节点的数组。
标签名称
标签名称是必需的参数。它可以是一个字符串,也可以是一个返回字符串的函数。
render
函数中可以访问 this
,所以可以将标签名称设置为 data
对象的某个属性、prop、计算属性等。
示例:
<script>
new Vue({
el:'#app',
render(createElement){
return createElement(this.tagName, 'Hello world!');
},
data:{
tagName:'h1'
}
});
</script>
数据对象
数据对象是设置一系列配置属性的地方,是标签名称与闭合尖括号之间的东西。
例如,对下面这行代码来说,
<custom-button type="submit" v-bind:text="buttonText">
其相应的属性就是: type="submit"
v-bind:text="buttonText"
。
在这个示例中, type
是传递给组件的一个普通的HTML属性,而 text
是一个组件 prop
,与变量 buttonText
绑定。
使用createElement
可以这样去写:
<script>
new Vue({
el:' #app',
render(createElement){
return createElement('custom-button',{
attrs:{
type:'submit'
},
props:{
text:this.buttonText
}
});
}
});
</script>
这里不再使用v-bind
了,因为可以直接通过this.buttonText
引用变量。由于this.buttonText
是render
函数的一个依赖,无论何时只要buttonText
更新,render
函数就会被再次调用,然后DOM
也会自动更新,这与template
是一致的。
所有的选项:
//HTML特性
attrs:{
type:'submit'
},
//传递给组件的prop
props:{
text:'单击我!'
},
//DOM属性,比如innerHTML(而不是v-html)
domProps:{
innerHTML:'一些HTML'
},
//事件侦听器
on:{
click: this.handleclick
},
//与slot="exampleSlot"相同,当组件是某个组件的子组件时使用
slot:'exampleSlot',
//与key="exampleKey"相同,用于某个循环产生的组件
key:'exampleKey',
//与ref="exampleRef"相同
ref:'exampleRef',
//与v-bind:class="['example-class',{'conditional-class':true}]相同
class: ['example-class', {'conditional-class': true}],
//与v-bind:style="{backgroundColor:'red'}”相同
style:{backgroundColor:'red'}
子节点
子节点可以是一个数组也可以是一个字符串。如果是一个字符串,那么它的值会作为元素的文本内容被输出;如果是一个数组,可以在数组中再次调用createElement
函数,来构建一个复杂的DOM树。
以下面这个模板为例:
<template>
<div>
<button v-on:click="count++">单击增加计数</button>
<p>已经单击了{{counter}}次。</p>
</div>
</template>
使用createElement
可以这样去写:
render(createElement){
return createElement(
'div',
[
createElement(
'button',
{
on:{
click:()=>this.count++,
}
},
'单击增加计数'
),
createElement(
'p',
你已经单击了按钮 ${this.counter}次。
)
]
);
}