VueJS渲染函数(render function)用法和原理详解

在上一节中,我们学习了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>
Vue组件的简单例子

现在,如果我们想重用组件,只需再次复制即可,例如

<div id="component_test">
        <testcomponent></testcomponent>
        <testcomponent></testcomponent>
        <testcomponent></testcomponent>
        <testcomponent></testcomponent>
    </div>
Vue重用组件实例

2、但是,现在我们需要对组件进行一些更改,我们不希望打印相同的文本,如何修改呢?若我们在组件中输入什么内容,会不会被输出呢?如下:

<div id="component_test">
        <testcomponent>A</testcomponent>
        <testcomponent>B</testcomponent>
        <testcomponent>C</testcomponent>
        <testcomponent>D</testcomponent>
    </div>
在Vue组件中添加内容

你可以看到,输出不是预期的结果,不会像我们想的那样改变文本。

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,因此现在它接收要发送到组件内部的值,如下面的截图所示。

组件使用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

它接受组件字段中分配的默认值。

下图是使用渲染函数在浏览器中的输出:

VueJS使用渲染函数在浏览器中的输出
微信公众号
手机浏览(小程序)
0
分享到:
没有账号? 忘记密码?