vue.js推荐使用的扩展名为vue的组件模板,可以让标签的属性和内容都变得动态,这是很强大也很已用的能力。但是,如果我需要标签名本身都是可以动态的话,怎么办?
比如我希望提供一个标签,可以根据属性值动态选择head的层级,像是把
header1
header2
可以替代为:
header1header2
答案就是render函数。具体做法就是首先注册一个组件:
Vue.component('hdr', { render:function(createElement){returncreateElement('h'+this.level,// tag namethis.$slots.default// array of children) }, props: { level: { type:Number, required:true} }})
随后在html内使用此组件:
//javascriptnew Vue({ el: '#example'})// htmlabcabc
可以执行的代码在此:
http://jsbin.com/xesihujuda/1...
函数render会传入一个createElement函数作为参数,你可以使用此函数来创建标签。第一个参数就是标签名称,以及为创建的标签提供属性和内容,以及创建子标签。在render函数内,可以通过this.$slots访问slot,从而把slot内的元素插入到当前被创建的标签内。为了方便,完整的使用createElement的实例代码抄写自vue.js手册。如下 :
createElement(// {String | Object | Function}// An HTML tag name, component options, or function// returning one of these. Required.'div',// {Object}// A data object corresponding to the attributes// you would use in a template. Optional.{// (see details in the next section below)},// {String | Array}// Children VNodes. Optional.[ createElement('h1','hello world'), createElement(MyComponent, { props: { someProp:'foo'} }),'bar'])
本来使用render的理由,就是我在封装bootstrap carousel的过程中产生的需要,如下代码是一个封装carousel的实际案例:
javascript
functionimg1(createElement,s){returncreateElement('img',{attrs:{src:'https://placehold.it/'+s}})}functionitem(createElement,isa,s){returncreateElement('div', {'class':{'item':true,'active':isa}}, [ img1(createElement,s) ])}functioninner(createElement){returncreateElement('div',{'class':{'carousel-inner':true}},[ item(createElement,true,'103X100') ,item(createElement,false,'101X100') ,item(createElement,false,'102X100') ])}functionleftcontrol(createElement){returncreateElement('a', { attrs:{'href':'#myCarousel1','data-slide':'prev','class':'carousel-control left'} }, [ left(createElement) ])}functionrightcontrol(createElement){returncreateElement('a', { attrs:{'href':'#myCarousel','data-slide':'prev','class':'carousel-control right'} }, [ right(createElement) ])}functionright(createElement){returncreateElement('span', { attrs:{'class':'glyphicon glyphicon-chevron-right'} }, [])}functionleft(createElement){returncreateElement('span', { attrs:{'class':'glyphicon glyphicon-chevron-left'} }, [])}Vue.component('mmm', { render:function(createElement){returncreateElement('div', {//'class':{'carousel':true, 'slide':true},attrs:{ id:'myCarousel1','class':'carousel slide','data-ride':'carousel'} }, [inner(createElement), leftcontrol(createElement), rightcontrol(createElement)] ) }})newVue({ el:'#example'})
html
可执行案例
http://jsbin.com/pulohup/edit...
参考