美文网首页
render函数

render函数

作者: 5吖 | 来源:发表于2019-03-16 23:54 被阅读0次

    一、初步了解

    1、 用template,但切记template下只允许有一个子节点

    //html
    ...
    <template id="msg">
      <div>
            <h1 v-if="level==1">
                <slot></slot>
            </h1>
            <h2 v-if="level==2">
                <slot></slot>
            </h2>
            <h3 v-if="level==3">
                <slot></slot>
            </h3>
      </div>
    </template>
    
    //js
    ...
    //用vue组件定义            
    Vue.component('my-component',{
     props:['level'],
     template:'#msg'
    })
              
    

    2、用render函数

    //js
    ...
    //用render函数定义组件
    Vue.component('my-component',{
      render:function (createElement) {
        return createElement('h'+this.level,
        this.$slots.default);
      },
      props:['level']
    })
    

    【Demo实例 https://jsbin.com/edit?html,output

    二、参数

    1、第一个参数

    ​ 在render函数的方法中,参数必须是createElement,createElement的类型是function
    ​ render函数的第一个参数是必选的,可以是 String | Object | Function

    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                //render 第一个参数必选,
                //String--html标签
                //Object--一个含有数据选项的对象
                //Function--方法返回一个含有数据选项的对象
                render:function(createElement){//createElement 是一个方法
                    alert(typeof createElement)
                    //return createElement('h1')
                    // return createElement({
                    //     template:'<div>hello world</div>'
                    // }) 
                    var domFun = function(){
                        return {
                            template:'<div>hello</div>'
                        }
                    }  
                    return createElement(domFun())             
                }
            }
        }
    })
    

    【Demo地址 https://jsbin.com/tiregac/edit?html,output

    2、第二个参数

    ​ render函数的第二个参数是可选,第二个参数是数据对象(只能是Object)

    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
               render:function(createElement){
                 return createElement({
                    template:'<div>hello world</div>'
                 },{
                    'class':{
                        foo:true,
                        bar:false
                    },
                    style:{
                        color: 'red',
                        fontSize:'16px'
                    },
                    //正常的html特性
                    attrs:{ // 也就是除了class,style之外的属性可以写在这
                        id:'foo',
                        src:'http://baidu.com'
                    },
                    //用来写原生的dom属性
                    domProps:{
                        innerHTML:'<span style="color:pink;font-size:18px">好的</span>'
                    }
                 })
               }
            }
        }
    })
    

    【Demo地址 https://jsbin.com/jegezil/1/edit?html,output

    3、第三个参数

    ​ 第三个参数是可选,可以是String | Array (作为我们构建函数的子节点来使用的)

    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                render:function(createElement){
                    return createElement('div',[
                        createElement('h1','我是h1标题'),
              //创建一个h1标签,它下面有一个文本节点,它的内容是:我是h1标题,创建好之后,会做为div的子节点
                        createElement('h6','我是h6标题')
                    ])
                }
            }
        }
    })
    

    【Demo实例https://jsbin.com/robayuj/edit?html,output

    三、 在render函数中使用this.$slots

    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                render:function(createElement){
                    debugger
                    var header = this.$slots.header //这返回含有vnode数据
                    var main = this.$slots.default
                    var footer = this.$slots.footer
                    return createElement('div',[ //第三个参数存的是vnode虚拟节点
                        createElement('header',header),//返回的就是vnode
                        createElement('main',main),
                        createElement('footer',footer)
                    ])
                }
            }
        }
    })
    

    【Demo实例https://jsbin.com/bonenab/edit?html,output

    四、在render函数中使用props传递数据

    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                render:function(createElement){
                    var imgsrc
                    if(this.show){
                        imgsrc='http://img4.c.yinyuetai.com/video/mv/190315/0/-M-4ee953619a011b7baad559bd52ace63f_240x135.jpg?t=20190314121758'
                    }else{
                        imgsrc='ihttp://img4.c.yinyuetai.com/video/mv/190315/0/-M-069ed9c6ed11e24de74292f800b033e5_240x135.jpg'
                    }
                    return createElement('img',{
                        attrs:{
                            src:imgsrc
                        },
                        style:{
                            width:'200px',
                            height:'200px'
                        }
                    })
                },
                props:['show']
            }
        },
        methods:{
            switchShow:function(){
                this.show = !this.show
            }
        },
        data:{
            show:false
        }
    })
    

    【Demo实例 https://jsbin.com/watazed/edit?html,output

    五、在render函数中使用v-model

    //html
    <div id="app">
        //<my-component :name=name @input="showName"></my-component>
                                 //3、v-model会自动接收
        <my-component :name=name v-model="name"></my-component>----{{name}}
    
        //1、v-model 本身绑定了 name
    
        //v-model ="name" 做了两件事:
       //a、接收了从子组件传递过来的数据
       //b、直接赋值给了绑定的name  
    </div>
    
    //js
    var app = new Vue({
       el: '#app',
       components:{
         'my-component':{
            render:function(createElment){
               var self = this //指的是当前的vue实例
               return createElment('input',{
                  domProps:{
                            value:self.name
                  },
                  on:{
                        input:function(event){
                           self.$emit('input',event.target.value)
                        }//2、你触发input事件,v-model绑定的本身就是input事件,然后往父组件传递数据时
                  }
                })
             },
             props:['name']
         }
       },
       data:{
            name: 'jack' //4、并把它赋值给绑定的name
       }
        // ,
        // methods:{
        //     showName:function(value){ //value是触发input事件后,传递过来的值
        //         this.name = value //接收一个数据,把这个数据赋值给 name 
        //     }
        // }
    })
    

    【Demo实例 https://jsbin.com/zawakaw/edit?html,output

    六、在render函数中使用作用域插槽

    //html
    <div id="app">
        <my-component>  //组件插槽传递数据:
            <template scope="prop">// 1、定义一个template模板,并用scope声明prop
                {{prop.text}} //2、用文本插值形式拿到要的值
                {{prop.msg}}
            </template>
        </my-component>
    </div>
    
    //js
    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                render:function(createElement){
                    //相当于<div><slot :text = "text"></slot></div>              
                    return createElement('div',this.$scopedSlots.default({
                        text: '我是子组件传递过来的数据',
                        msg:'scopetext'
                    }))
                }
            
            }
        }
    })
    
    

    【Demo实例https://jsbin.com/ralinum/edit?html,output

    七、函数化组件的应用

    // this.text-----context.props.text
    // this.$slots.default-----context.children
    
    var app = new Vue({
        el: '#app',
        components:{
            'my-component':{
                functional:true,//当前的vue实例无状态,无实例
                render:function(createElement,context){
                    return createElement('button',{
                        on:{
                            click:function(){
                                console.log(context)
                                alert(context.parent.msg)
                                alert(context.props.value)
                                console.log('this.value',a.value) //undefined
                            }
                        }
                    },'点击我学习')
                },
                props:['value']
            }
        },
        data:{
            msg:'我是父组件的内容'
        }
    })
    

    【Demo实例https://jsbin.com/tuvunam/1/edit?html,output

    相关文章

      网友评论

          本文标题:render函数

          本文链接:https://www.haomeiwen.com/subject/vkxymqtx.html