码迷,mamicode.com
首页 > Web开发 > 详细

简单 实现 Vue.js 的v-if v-show 指令

时间:2021-01-25 10:44:54      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:length   rip   cli   nod   ice   htm   char   button   处理   

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #main {
            position: absolute;
            top: 0;
            left: 0;
        }
        #main div {
            float: left;
            width: 100px;
            height: 100px;
            text-align: center;
            line-height: 100px;
            color: white;
        }
        .div1 {
            background-color: aquamarine;
        }
        .div2 {
            background-color: orange;
        }
        .div3 {
            background-color: orchid;
        }
        .div4 {
            background-color: royalblue;
        }
    </style>
</head>
<body>
    <div id="main">
        <div class="div1" v-if="if1"></div>
        <div class="div2" v-show="show1"></div>
        <div class="div3" v-if="if2"></div>
        <div class="div4" v-show="show2"></div>
        <br><br>
        <button @click="click1">天-if</button>
        <button @click="click2">地-show</button>
        <button @click="click3">雷-if</button>
        <button @click="click4">霆-show</button>
    </div>
    <script>
        class Winter {  // 这个类是为了实现类似Vue的v-if v-show指令
            constructor(o) {
                // 定义依赖收集对象
                this.instrList = {};
                // 接收并处理传递的参数
                let { el, data, methods } = o;
                this.el = document.querySelector(el);
                this.data = data;
                this.methods = methods;
                // 代理data数据
                this.proxyData();
                // 解析DOM模版
                this.parseDOM(this.el);
                // 初始化DOM节点状态
                for (let key in this.data) {
                    this.opDOM(key);
                }
            }

            proxyData() {  // 代理数据
                for (let key in this.data) {
                    Object.defineProperty(this, key, {
                        get: function () {
                            return this.data[key];
                        }, 
                        set: function (value) {
                            this.data[key] = value;
                            // 当响应式数据发生改变时
                            this.opDOM(key);
                        }
                    });
                }
            }

            parseDOM(e) {  // 解析模板 收集依赖
                let t1 = e.getAttribute(v-if);
                let t2 = e.getAttribute(v-show);
                let t3 = e.getAttribute(@click);
                if (t1 != null) {  // 处理IF指令
                    this.instrList[t1] == void 0 && (this.instrList[t1] = []);
                    this.instrList[t1].push({
                        type: if, 
                        e: e, 
                        real: e, 
                        standIn: document.createComment(if)
                    });
                }
                if (t2 != null) {  // 处理SHOW指令
                    this.instrList[t2] == void 0 && (this.instrList[t2] = []);
                    this.instrList[t2].push({
                        type: show, 
                        e: e
                    });
                }
                if (t3 != null) {  // 处理事件绑定
                    e.onclick = this.methods[t3].bind(this);
                }
                // 递归处理所有子节点
                let list = e.childNodes;
                for (let i = 0, len = list.length; i < len; ++i) {
                    if (list[i].nodeType == 1) {
                        this.parseDOM(list[i]);
                    }
                }
            }

            opDOM(key) {  // 操作DOM
                let t = this.instrList[key];
                for (let i = 0, len = t.length; i < len; ++i) {
                    if (t[i].type == if) {
                        this.data[key] ? 
                        (t[i].e.parentNode.replaceChild(t[i].real, t[i].e), t[i].e = t[i].real) : 
                        (t[i].e.parentNode.replaceChild(t[i].standIn, t[i].e), t[i].e = t[i].standIn);
                    } else {
                        t[i].e.style.display = this.data[key] ? block : none;
                    }
                }
            }

        }

        new Winter({
            el: #main, 
            data: {
                if1: true, 
                show1: true, 
                if2: true, 
                show2: true
            }, 
            methods: {
                click1: function () {
                    this.if1 = !this.if1;
                }, 
                click2: function () {
                    this.show1 = !this.show1;
                }, 
                click3: function () {
                    this.if2 = !this.if2;
                }, 
                click4: function () {
                    this.show2 = !this.show2;
                }
            }
        });
    </script>
</body>
</html>

 

简单 实现 Vue.js 的v-if v-show 指令

标签:length   rip   cli   nod   ice   htm   char   button   处理   

原文地址:https://www.cnblogs.com/beiyudaoke/p/14313815.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!