Render函数(3):函数式组件、JSX初接触

写在前面:说实话视频学习的方式真的不适合我...之前在B站和慕课上的Vue视频学的组件啊Vuex啊router真的只是囫囵吞枣啊,会用是会用,但是呆的很。

还是纸质适合我,应该这一周就能复习完Vuex和router了,冲!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="Vue.2.6.10.js"></script>
</head>
<body>
    <div id="app1">
        <smart-item :data='data'></smart-item>
        <button @click='change("img")'>切换至图片组件</button>
        <button @click='change("video")'>切换至视频组件</button>
        <button @click='change("text")'>切换至文字组件</button>
    </div>
</body>
<script>
    //vue提供了一个functional的布尔值选项(注册组件时),若设置为true,则会使得组件无状态、无实例,即没有data、this上下文,这样使用render函数
    //返回的虚拟节点可以更容易渲染,因为函数化的组件只是一个函数(即functional为true)
    //图片组件选项
    var imgComp = {
        props:['data'],
        render(h) {
            return createElement('div',[
                createElement('p','图片组件'),
                createElement('img',{
                    attrs:{
                        src:this.data.url
                    }
                })
            ]);
        },
    };

    var videoComp = {
        props:['data'],
        render:function(createElement){
            return createElement('div',[
                createElement('p','视频组件'),
                createElement('video',{
                    attrs:{
                        src:this.data.url,
                        controls:'controls',
                        autoplay:'autoplay'
                    }
                })
            ]);
        }
    };

    var textComp = {
        props:['data'],
        render:function(createElement){
            return createElement('div',[
                createElement('p','文本组件'),
                createElement('p',this.data.text)
            ]);
        }
    };

    Vue.component('smart-item',{
        //函数化组件
        functional:true,
        render:function(createElement,context){//使用函数化组件时,render函数提供了第二个参数context
        //来提供临时上下文,组件中需要的data、props、slots、children、parent都是通过它来传递的
        //this.level---context.props.level, this.$slots.default---context.children
            function getCom(){
                var data = context.props.data;
                if(data.type === 'img') return imgComp;
                if(data.type === 'video') return videoComp;
                return textComp;
            };
            return createElement(
                getCom(),
                {
                    props:{
                        data:context.props.data//从组件smart-item传向上面getCom()返回的组件             
                    }
                },
                context.children//父组件插槽的默认内容
            )
        },
        props:{
            data:{
                type:Object,
                required:true
            }
        }
    });

    var app1 = new Vue({
       el:"#app1",
       data:{
           data:{}//默认为对象嗷
       },
       methods: {
           change:function(type){
               if(type === 'img'){
                   this.data = {
                       type:'img',
                       url:''
                   }
               }else if(type === 'video'){
                   this.data = {
                       type:'video',
                       url:''
                   }
               }else if(type === 'text'){
                   this.data = {
                       type:'text',
                       text:'文本组件,冲!'
                   }
               }
           }
       },
       created() {
           this.change('text');
       },
    });


    //jsx是什么?它是一种看起来像html,但实际上是js的语法扩展
    // // createElement&jsx:
    // render(createElement){
    //     return createElement('div',{
    //         props:{
    //             text:'some text'
    //         },
    //         attrs:{
    //             id:'myDiv'
    //         },
    //         domProps:{
    //             innerHTML:'content'
    //         },
    //         on:{
    //             change:this.change
    //         },
    //         nativeOn:{
    //             click:this.clickHandler
    //         },
    //         class:{
    //             show:true,
    //             on:false
    //         },
    //         style:{
    //             color:"#fff",
    //             background:'#f50'
    //         },
    //         key:'key',
    //         ref:'element',
    //         slot:'slot'
    //     })
    // };//改写为jsx如下:
    // render(h) {
    //     return {
    //         <div 
    //             id='myDiv'
    //             domPropsInnerHTML='content'
    //             onChange = {this.change}
    //             class={{ show:true, on:false }}
    //             style = {{ ... }}

    //     }
    // }
</script>
</html>
原文地址:https://www.cnblogs.com/linbudu/p/11082150.html