Vue render深入开发讲解
简介
在使用Vue进行开发的时候,大多数情况下都是使用template进行开发,使用template简单、方便、快捷,可是有时候需要特殊的场景使用template就不是很适合。因此为了很好使用render函数,我决定深入窥探一下。各位看官如果觉得下面写的有不正确之处还望看官指出,你们与我的互动就是写作的最大动力。
场景
官网描述的场景当我们开始写一个通过levelprop动态生成heading标签的组件,你可能很快想到这样实现:
Vue.component('anchored-heading',{
template:'#anchored-heading-template',
props:{
level:{
type:Number,
required:true
}
}
})
在这种场景中使用template并不是最好的选择:首先代码冗长,为了在不同级别的标题中插入锚点元素,我们需要重复地使用
虽然模板在大多数组件中都非常好用,但是在这里它就不是很简洁的了。那么,我们来尝试使用render函数重写上面的例子:
Vue.component('anchored-heading',{
render:function(createElement){
returncreateElement(
'h'+this.level,//tagname标签名称
this.$slots.default//子组件中的阵列
)
},
props:{
level:{
type:Number,
required:true
}
}
})
简单清晰很多!简单来说,这样代码精简很多,但是需要非常熟悉Vue的实例属性。在这个例子中,你需要知道当你不使用slot属性向组件中传递内容时,比如anchored-heading中的Helloworld!,这些子元素被存储在组件实例中的$slots.default中。
createElement参数介绍
接下来你需要熟悉的是如何在createElement函数中生成模板。这里是createElement接受的参数:
createElement(
//{String|Object|Function}
//一个HTML标签字符串,组件选项对象,或者
//解析上述任何一种的一个async异步函数,必要参数。
'div',
//{Object}
//一个包含模板相关属性的数据对象
//这样,您可以在template中使用这些属性。可选参数。
{
//(详情见下一节)
},
//{String|Array}
//子节点(VNodes),由`createElement()`构建而成,
//或使用字符串来生成“文本节点”。可选参数。
[
'先写一些文字',
createElement('h1','一则头条'),
createElement(MyComponent,{
props:{
someProp:'foobar'
}
})
]
)
深入data对象
有一件事要注意:正如在模板语法中,v-bind:class和v-bind:style,会被特别对待一样,在VNode数据对象中,下列属性名是级别最高的字段。该对象也允许你绑定普通的HTML特性,就像DOM属性一样,比如innerHTML(这会取代v-html指令)。
{
//和`v-bind:class`一样的API
'class':{
foo:true,
bar:false
},
//和`v-bind:style`一样的API
style:{
color:'red',
fontSize:'14px'
},
//正常的HTML特性
attrs:{
id:'foo'
},
//组件props
props:{
myProp:'bar'
},
//DOM属性
domProps:{
innerHTML:'baz'
},
//事件监听器基于`on`
//所以不再支持如`v-on:keyup.enter`修饰器
//需要手动匹配keyCode。
on:{
click:this.clickHandler
},
//仅对于组件,用于监听原生事件,而不是组件内部使用
//`vm.$emit`触发的事件。
nativeOn:{
click:this.nativeClickHandler
},
//自定义指令。注意,你无法对`binding`中的`oldValue`
//赋值,因为Vue已经自动为你进行了同步。
directives:[
{
name:'my-custom-directive',
value:'2',
expression:'1+1',
arg:'foo',
modifiers:{
bar:true
}
}
],
//Scopedslotsintheformof
//{name:props=>VNode|Array}
scopedSlots:{
default:props=>createElement('span',props.text)
},
//如果组件是其他组件的子组件,需为插槽指定名称
slot:'name-of-slot',
//其他特殊顶层属性
key:'myKey',
ref:'myRef'
}
条件渲染
既然熟读以上api接下来咱们就来点实战。
之前这样写
//HTML我被你发现啦!!!