template不行?使用render函数开发动态组件
背景
今天在开发某个需求的时候遇到了一个问题,某个组件的一些html标签需要根据props定义的tag字段自定义传入,生成对应的div、p、span等标签显示在页面中,并且tag不固定(排除了枚举所有标签并使用v-if控制实现的可能)。但是vue2.x的模板语法只支持在template中添加某些确定的标签,无法实现,于是想到了使用render函数来实现。
用法:
Vue推荐在大多数的情况下使用模板创建html,然而在一些模板语法不能满足的特殊场景下,我们可以通过render函数使用JavaScript来构建dom。例如:
render(createElement){
return createElement('div','这是需要显示的文字')
}
使用vue进行开发的人员都知道,Vue通过创建一个虚拟dom来追踪自己想要改变的真实dom。所以createElement返回的并不是一个真实的dom,官网给了一个更准确名字createNodeDescription:因为它包含的信息会告诉vue页面上需要渲染什么样的节点,包括及其子节点的描述信息。这样的节点被称为虚拟节点(virtual node),也就是常说的VNode。
createElement的三个参数:
【1】String | Object | Function :必填,可以是一个html标签,或者包含标签数据的
【2】Object : class | style | attrs | domProps | on 等
【3】String | Array
注意:
template模板语法不能跟render函数连用,render优先并且会覆盖模板内容。
最后使用render函数完成的核心代码如下:
<script>
export default {
name:'ai-row',
methods:{
handleClick(e){
this.$emit('click',e);
}
},
render(createElement){
return createElement(
this.tag,
{
props:{
tag:{
type:String,
default:'div'
},
classes:{
type:Array,
default:()=>['ai-row']
}
},
class:this.classes,
style:{
fontSize:'14px'
},
attrs:{
id:'ai-row-main',
placeholder:'在此输入...'
},
domProps:{
ref:'rowRef'
},
on:{
click:(e)=>{
this.handleClick(e);
}
}
},
this.$slots.default
)
}
}
</script>

浙公网安备 33010602011771号