在上一节中,我们学习了VueJS混入mixins的用法,混入一般和组件一起使用,要注意混入mixins和Vue实例或组件有同名方法时的执行情况。本节我们来学下VueJS的渲染函数的用法和原理,我们之前已经学习了组件及其用法,例如,我们有一个需要在整个项目中重用的内容,我们可以将其转换为组件并使用它。
1、下面我们来看一个简单组件的例子,看看渲染函数的用法,以及在其中的作用和原理。
<testcomponent></testcomponent>
</div>
<script type="text/javascript">
Vue.component('testcomponent', {
template: '<h1>Hello World</h1>',
data: function () {
},
methods: {
}
});
var vm = new Vue({
el: '#component_test'
});
</script>
现在,如果我们想重用组件,只需再次复制即可,例如
<div id="component_test">
<testcomponent></testcomponent>
<testcomponent></testcomponent>
<testcomponent></testcomponent>
<testcomponent></testcomponent>
</div>
2、但是,现在我们需要对组件进行一些更改,我们不希望打印相同的文本,如何修改呢?若我们在组件中输入什么内容,会不会被输出呢?如下:
<div id="component_test">
<testcomponent>A</testcomponent>
<testcomponent>B</testcomponent>
<testcomponent>C</testcomponent>
<testcomponent>D</testcomponent>
</div>
你可以看到,输出不是预期的结果,不会像我们想的那样改变文本。
3、组件提供了一些称为插槽slot的东西,我们可以使用它,看看我们是否得到了想要的结果。
<div id="component_test">
<testcomponent>A</testcomponent>
<testcomponent>B</testcomponent>
<testcomponent>C</testcomponent>
<testcomponent>D</testcomponent>
</div>
<script type="text/javascript">
Vue.component('testcomponent', {
template: '<h1><slot></slot></h1>',
data: function () {
},
methods: {
}
});
var vm = new Vue({
el: '#component_test'
});
</script>
正如在上面的代码中看到的,在模板中我们添加了slot,因此现在它接收要发送到组件内部的值,如下面的截图所示。
4、现在,假设我们想要改变颜色和大小。例如,目前我们正在使用h1标签,我们希望将相同组件的HTML标签更改为p标签或div标签,如何能灵活地进行这么多的改变呢?
我们可以在渲染函数的帮助下做到这一点,渲染函数(Render function)有助于使组件变得动态,并通过保持它的通用性和使用相同的组件传递参数来使用它。
<div id="component_test">
<testcomponent :elementtype="'div,red,25,div1'">Apple</testcomponent>
<testcomponent :elementtype="'h3,green,25,h3tag'">Bubble</testcomponent>
<testcomponent :elementtype="'p,blue,25,ptag'">Cat</testcomponent>
<testcomponent :elementtype="'div,green,25,divtag'">Dog</testcomponent>
</div>
<script type="text/javascript">
Vue.component('testcomponent', {
render: function (createElement) {
var a = this.elementtype.split(",");
return createElement(a[0], {
attrs: {
id: a[3],
style: "color:" + a[1] + ";font-size:" + a[2] + ";"
}
},
this.$slots.default
)
},
props: {
elementtype: {
attributes: String,
required: true
}
}
});
var app = new Vue({
el: '#component_test'
});
</script>
在上面的代码中,我们使用下面的代码更改了组件并添加了带有props属性的render函数。
Vue.component('testcomponent', {
render: function (createElement) {
var a = this.elementtype.split(",");
return createElement(a[0], {
attrs: {
id: a[3],
style: "color:" + a[1] + ";font-size:" + a[2] + ";"
}
},
this.$slots.default
)
},
props: {
elementtype: {
attributes: String,
required: true
}
}
});
Props如下所示:
props: {
elementtype: {
attributes: String,
required: true
}
}
我们已经定义了一个名为elementtype的属性,它接受string类型的属性字段。另一个必填字段,其中提到该字段是必填项。
在render渲染函数中,我们使用了elementtype属性,如下面的代码段所示。
render: function (createElement) {
var a = this.elementtype.split(",");
return createElement(a[0], {
attrs: {
id: a[3],
style: "color:" + a[1] + ";font-size:" + a[2] + ";"
}
},
this.$slots.default
)
}
Render函数以createElement作为参数并返回相同的结果。CreateElement以与JavaScript相同的方式创建DOM元素,我们还使用attrs字段中的值在逗号上拆分elementtype。
CreateElement将第一个参数作为要创建的elementtag,它使用下面的代码段传递给组件。
<testcomponent :elementtype="'div,red,25,div1'">Apple</testcomponent>
组件需要获取如上所示的props字段。它以:和props的名字开始。在这里,我们传递元素标记、颜色、字体大小和元素的id。
在render
function、createElement中,我们使用逗号分隔元素,因此第一个元素是elementtag,它被赋予createElemet,如下面的代码段所示。
return createElement(a[0], {
attrs: {
id: a[3],
style: "color:" + a[1] + ";font-size:" + a[2] + ";"
}
},
this.$slots.default
)
a[0]是html元素标签,下一个参数是元素的属性,它们在以下代码段的attr字段中定义。
attrs: {
id: a[3],
style: "color:" + a[1] + ";font-size:" + a[2] + ";"
}
我们已经为元素定义了两个属性—id和style。对于id,我们传递一个a[3],它是我们在分隔逗号后得到的值。使用style,我们定义了颜色和字体大小。
最后是slot,这是我们在下面的代码段组件中给出。
<testcomponent :elementtype="'div,red,25,div1'">Apple</testcomponent>
我们已经使用以下代码段定义了要在createElement中打印的文本。
this.$slots.default
它接受组件字段中分配的默认值。
下图是使用渲染函数在浏览器中的输出: