美文网首页
vue双向绑定原理

vue双向绑定原理

作者: 阿水日记 | 来源:发表于2019-06-15 19:20 被阅读0次
    <script>
            //发布者
            class Vue {
                constructor(options) {
                    this.options = options
                    this.$data = options.data
                    this.$el = document.querySelector(options.el)
                    this._directives = {} //存放订阅了对应数据的(什么东西)
                    //{myText:[订阅者1,订阅者2],mybox:[订阅者1]}
                    this.Observer(this.$data)
                    this.Compile(this.$el)
                }
                //劫持数据
                Observer(data) {
                    //更新视图
                    for (let key in data) {
                        this._directives[key] = []
                        let _this = this._directives[key]
                        let val = data[key] //当前值
                        Object.defineProperty(this.$data, key, {
                            get: function () {
                                return val
                            },
                            set: function (newVal) {
                                if (newVal !== val) {
                                    val = newVal
                                    //[订阅者1,订阅者2]
                                    _this.forEach(watch => {
                                        watch.update()
                                    });
                                }
                            }
                        })
                    }
    
    
                }
                //解析指令
                Compile(el) {
                    let nodes = el.children //获取根节点下的子元素
                    for (let i = 0; i < nodes.length; i++) {
                        let node = nodes[i] //当前元素
                        if (node.children.length) {//如果还有子节点
                            this.Compile(node)
                        }
                        if (node.hasAttribute("v-text")) { //查找v-text
                            let attrVal = node.getAttribute("v-text")
                            this._directives[attrVal].push(new Watch(node, attrVal, this, 'innerHTML'))
                        }
    
                        if (node.hasAttribute("v-model")) { //查找vmodel
                            let attrVal = node.getAttribute("v-model")
                            this._directives[attrVal].push(new Watch(node, attrVal, this, 'value'))
                            let _this = this
                            node.addEventListener("input", (function () {
                                return function () {
                                    //更新视图到模型
                                    _this.$data[attrVal] = node.value
                                }
                            })())
                        }
                    }
                }
            }
            //订阅者
            class Watch {
                constructor(el, vm, mySelf, attr) {
                    this.el = el
                    this.vm = vm
                    this.mySelf = mySelf
                    this.attr = attr
                    this.update()
                }
                update() {
                    this.el[this.attr] = this.mySelf.$data[this.vm]
                    //div对象[innerHTML]=vue对象.data["myText"]   
                }
            }
        </script>
    
    <body>
        <div id="app">
            <h1>数据响应式</h1>
            <div>
                <div v-text="myText"></div>
                <input type="text" v-model="myText">
            </div>
        </div>
    </body>
    <script>
        new Vue({
            el: '#app',
            data: {
                myText: '大吉大利,今晚吃鸡'
            }
        })
    </script>
    

    相关文章

      网友评论

          本文标题:vue双向绑定原理

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