为了账号安全,请及时绑定邮箱和手机立即绑定

说说 Vue.js 中的 functional 函数化组件

标签:
Vue.js

webp

Vue.js 组件提供了一个 functional  开关,设置为 true 后,就可以让组件变为无状态、无实例的函数化组件。因为只是函数,所以渲染的开销相对来说,较小。

函数化的组件中的 Render 函数,提供了第二个参数 context 作为上下文,data、props、slots、children 以及 parent 都可以通过 context 来访问。

1 示例

这里,我们用  functional 函数化组件来实现一个智能组件。

html:

<div id="app">    <smart-component :data="data"></smart-component>
    <button @click="change('img')">图片组件</button>
    <button @click="change('video')">视频组件</button>
    <button @click="change('text')">文本组件</button></div>

js:

//图片组件设置var imgOptions = {    props: ['data'],    render: function (createElement) {        return createElement('div', [
            createElement('p', '图片组件'),
            createElement('img', {                attrs: {                    src: this.data.url,                    height: 300,                    weight: 400

                }
            })
        ]);
    }
};//视频组件设置var videoOptions = {    props: ['data'],    render: function (createElement) {        return createElement('div', [
            createElement('p', '视频组件'),
            createElement('video', {                attrs: {                    src: this.data.url,                    controls: 'controls',                    autoplay: 'autoplay'
                }
            })
        ]);
    }
};//文本组件设置var textOptions = {    props: ['data'],    render: function (createElement) {        return createElement('div', [
            createElement('p', '文本组件'),
            createElement('p', this.data.content)
        ]);
    }
};

Vue.component('smart-component', {    //设置为函数化组件
    functional: true,    render: function (createElement, context) {        function get() {            var data = context.props.data;            console.log("smart-component/type:" + data.type);            //判断是哪一种类型的组件
            switch (data.type) {                case 'img':                    return imgOptions;                case 'video':                    return videoOptions;                case 'text':                    return textOptions;                default:                    console.log("data 类型不合法:" + data.type);
            }
        }        return createElement(
            get(),
            {                props: {                    data: context.props.data
                }
            },
            context.children
        )
    },    props: {        data: {            type: Object,            required: true
        }
    }
})var app = new Vue({    el: '#app',    data: {        data: {}
    },    methods: {        change: function (type) {            console.log("输入类型:" + type);            switch (type) {                case 'img':                    this.data = {                        type: 'img',                        url: 'http://pic-bucket.ws.126.net/photo/0001/2019-02-07/E7D8PON900AO0001NOS.jpg'
                    }                    break;                case 'video':                    this.data = {                        type: 'video',                        url: 'http://wxapp.cp31.ott.cibntv.net/6773887A7F94A71DF718E212C/03002002005B836E73A0C5708529E09C1952A1-1FCF-4289-875D-AEE23D77530D.mp4?ccode=0517&duration=393&expire=18000&psid=bbd36054f9dd2b21efc4121e320f05a0&ups_client_netip=65600b48&ups_ts=1549519607&ups_userid=21780671&utid=eWrCEmi2cFsCAWoLI41wnWhW&vid=XMzc5OTM0OTAyMA&vkey=A1b479ba34ca90bcc61e3d6c3b2da5a8e&iv=1&sp='
                    }                    break;                case 'text':                    this.data = {                        type: 'text',                        content: '《流浪地球》中的科学:太阳何时吞并地球?科学家已经给出时间表'
                    }                    break;                default:                    console.log("data 类型不合法:" + type);
            }

        }
    },    created: function () {        //默认为图片组件
        this.change('img');
    }

});

效果:

webp

  • 首先定义了图片组件设置对象、视频组件设置对象以及文本组件设置对象,它们都以 data 作为入参。

  • 函数化组件 smart-component,也以  data 作为入参。内部根据 get() 函数来判断需要渲染的组件类型。

  • 函数化组件 smart-component 的 render 函数,以 get() 作为第一个参数;以 smart-component 所传入的 data,作为第二个参数:

return createElement(    get(),
    {        props: {
            data: context.props.data
        }
    },    context.children)
  • 根实例 app 的 change 方法,根据输入的类型,来切换不同的组件所需要的数据。



作者:deniro
链接:https://www.jianshu.com/p/367ba1a7729b


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消