Render函数(2):使用原生js替代自定义指令、修饰符、slot

<!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">
        <ele1 :show="show"></ele1>
        <button @click="show = !show">切换show的值</button>
    </div>

    <div id="app2">
        <ele2 :list='list'></ele2>
    </div>

    <div id="app3">
        <ele3 :list='list'></ele3>
        <button @click='handleClick'>显示列表</button>
    </div>

    <div id="app4">
        <ele4></ele4>
    </div>

    <div id="app5">
        <ele5></ele5>
    </div>

    <div id="app6">
        <ele6>
            <p>有我在,备用内容不会出现</p>
        </ele6>
    </div>
</body>
<script>
    //在render函数中,不再需要也无法使用Vue的内置指令,如v-if、v-show,但均可通过原生js实现
    //数据变化--render函数生成新的虚拟dom--更新
    Vue.component('ele1',{
        render(createElement) {
            if(this.show){
                return createElement('p','show的值为true');
            }else{
                return createElement('p','show的值为false');
            }
        },
        props:{
            show:{
                type:Boolean,
                default:false
            }
        }
    });

    var app1 = new Vue({
        el:"#app1",
        data:{
            show:false
        }
    });

    //使用for循环来实现v-for
    Vue.component('ele2',{
        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 app2 = new Vue({
        el:"#app2",
        data:{
            list:[
                'book1',
                'book2',
                'book3'
            ]
        }
    });

    //使用if、else、数组map方法配合来渲染一个列表
    Vue.component('ele3',{
        render:function(createElement){
            if(this.list.length){
                return createElement('ul',this.list.map(function(item){
                    return createElement('li',item);
                }));
            }else{
                return createElement('p','列表当前为空')
            }
        },
        props:{
            list:{
                type:Array,
                default:function(){
                    return []
                }
            }
        }
    });

    var app3 = new Vue({
       el:"#app3",
       data:{
           list:[]
       },
       methods: {
           handleClick:function(){
               //点击后才会将项目添加到列表
                this.list = [
                'book11',
                'book22',
                'book33'
            ]
           }
       },
    });

    //实现v-model逻辑
    Vue.component('ele4',{
        render:function(createElement){
            var _this = this;
            return createElement('div',[
                createElement('input',{
                    domProps:{
                        value:this.value
                    },
                    on:{
                        input:function(event){
                            _this.value = event.target.value;
                        }
                    }
                }),
                createElement('p','value: '+ this.value)
            ])
        },
        data() {
            return {
                value:''
            }
        },
    });

    var app4 = new Vue({
        el:'#app4'
    });

//所有的事件修饰符与按键修饰符同样需要自己实现
//.stop  event.stopPropogation()
//.prevent event.preventDefault()
//.self if(e.target !== e.currentTarget)
//.enter  .13 if(event.keyCode !== 13)
//.ctrl/.alt if(!e.ctrlKey/altKet)return
//.capture(!) .once(~)
//capture先执行父级事件再执行子级事件  self只执行子级事件 
//模拟聊天发生内容场景

Vue.component('ele5',{
    render:function(createElement){
        var _this = this;
        //渲染聊天内容列表
        if(this.list.length){
            var listNode = createElement('ul',this.list.map(function(item){
                return createElement('li',item)
            }));
        }else{
            var listNode = createElement('p','暂无内容');
        }
        return createElement('div',[
            listNode,
            createElement('input',{
                attrs:{
                    placeholder:'回车发送'
                },
                style:{
                    width:'200px'
                },
                on:{
                    keyup:function(e){
                        if(e.keyCode != 13) return;
                        _this.list.push(e.target.value);
                        e.target.value = '';//发送成功清空输入框
                    }
                }
            })
        ])
    },
    data() {
        return {
            value:'',
            list:[]
        }
    },
});

var app5 = new Vue({
    el:"#app5" 
});

Vue.component('ele6',{
    render:function(createElement){
        console.log(this.$slots.default);
        if(this.$slots.default === undefined){
            return createElement('div','备用内容')
        } else {
            return createElement('div',this.$slots.default);
        }
    }
});

var app6 = new Vue({
    el:'#app6' 
});
</script>
</html>

 

posted @ 2019-06-24 15:18  林不渡  阅读(922)  评论(0编辑  收藏  举报