Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能

约束

    所有的组件树中,如果 VNode 是组件或含有组件的 slot,那么 VNode 必须唯一。

    重复渲染多个组件(或元素)

<div id="app">
    <ele></ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    //局部声明组件
    var Child = {
        render:function(createElement){
            return createElement('p','text');
        }
    };
    Vue.component('ele',{
        render:function(createElement){
            return createElement('div',
                Array.apply(null,{
                    length:5
                }).map(function(){
                    return createElement(Child);
                })
            );
        }
    });
    var app = new Vue({
        el:'#app'
    })
</script>

Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能

    含有组件的 slot复用

<div id="app">
    <ele>
        <div>
            <Child></Child>
        </div>
    </ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    //全局注册组件
    Vue.component('Child',{
        render:function(createElement){
            return createElement('p','text');
        }
    });
    Vue.component('ele',{
        render:function(createElement){
            //克隆slot节点的方法
            function cloneVNode(vnode){
                //递归遍历所有子节点,并克隆
                const cloneChildren = vnode.children&&
                    vnode.children.map(function(vnode){
                        return cloneVNode(vnode);
                    });
                const cloned = createElement(
                    vnode.tag,
                    vnode.data,
                    cloneChildren
                );
                cloned.text = vnode.text;
                cloned.isComment = vnode.isComment;
                cloned.componentOptions = vnode.componentOptions;
                cloned.elm = vnode.elm;
                cloned.context = vnode.context;
                cloned.ns = vnode.ns;
                cloned.isStatic = vnode.isStatic;
                cloned.key = vnode.key;

                return cloned;
            }
            const vNodes = this.$slots.default;
            const cloneVNodes = vNodes.map(function(vnode){
                return cloneVNode(vnode);
            });
            return createElement('div',[
                vNodes,
                cloneVNodes
            ]);
        }
    });
    var app = new Vue({
        el:'#app'
    })
</script>

Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能

 使用 JavaScript 代替模板功能

    在Render函数中,不再需要Vue内置的指令,比如v-if、v-for,当然,也没办法使用它们。无论要实现什么功能,都可以用原生JavaScript。

     v-if、v-else

<div id="app">
    <ele :show="show"></ele>
    <button @click="show=!show">切换show</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
    Vue.component('ele',{
        render:function(createElement){
            if(this.show){
                return createElement('p','show的值为true');
            }else{
                return createElement('p','show的值为false');
            }
        },
        props:{
            show:{
                type:Boolean,
                default:false
            }
        }
    });
    var app = new Vue({
        el:'#app',
        data:{
            show:false
        }
    })
</script>

Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能

    v-for

<div id="app">
   <ele :list="list"></ele>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script>
   Vue.component('ele',{
       render:function(createElement){
           var nodes = [];
           for(var i=0;i<this.list.length;i++){
               nodes.push(createElement('p',this.list[i]));
           }
           return createElement('div',nodes);
       },
       props:{
           list:{
               type:Array
           }
       }
   });
   var app = new Vue({
       el:'#app',
       data:{
           list:[
               '《西游记》',
               '《三国演义》',
               '《红楼梦》',
               '《水浒传》'
           ]
       }
   })
</script>

Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能

 

Vue.js入门 0xC Render函数(2)约束、JavaScript代替模板功能