雙向綁定簡單實現(xiàn)

https://www.jb51.net/article/172633.htm

function Vue(options){
    this.$data = options.data
    this.$el = document.querySelector(options.el)

    this.derevtive = {}

    this.Observer(this.$data)
    this.Compile(this.$el)
}

Vue.prototype.Observer = function(data){
    for(let key in data){
        this.derevtive[key] = []
        let direct = this.derevtive[key]
        let oldVal = data[key]

        Object.defineProperty(this.$data, key, {
            get(){
                return oldVal
            },
            set(newVal){
                if(newVal !== oldVal){
                    oldVal = newVal
                    direct.forEach(item=>{
                        item.updata()
                    })
                }
            }
        })
    }
}

Vue.prototype.Compile = function(node){
    let nodes = node.children
    for(let i=0,len=nodes.length;i<len;i++){
        let nodeChild = nodes[i]
        if(nodeChild.children.length){
            this.Compile(nodeChild)
        }

        if(nodeChild.hasAttribute('v-text')){
            let attr = nodeChild.getAttribute('v-text')
            this.derevtive[attr].push(new Watcher({
                nodeChild,
                type: 'innerText',
                vm: this,
                attr
            }))
        }

        if(nodeChild.hasAttribute('v-model')){
            let attr = nodeChild.getAttribute('v-model')
            this.derevtive[attr].push(new Watcher({
                nodeChild,
                type: 'value',
                vm: this,
                attr
            }))
            nodeChild.addEventListener('input', ()=>{
                this.$data[attr] = nodeChild.value
            })
        }
    }
}


function Watcher(options){
    this.nodeChild = options.nodeChild
    this.type = options.type
    this.vm = options.vm
    this.attr = options.attr
    this.updata()
}

Watcher.prototype.updata = function(){
    this.nodeChild[this.type] = this.vm.$data[this.attr]
}

https://zhuanlan.zhihu.com/p/282763032

class Vue {
    constructor(options){
        this.$data = options.data
        this.$el = document.querySelector(options.el)
        
        this.derevtive = {}

        this.Observer(this.$data)
        this.Compile(this.$el)
    
    }

    // 數(shù)據(jù)劫持,代理所有的數(shù)據(jù)
    Observer(data){
        for(let key in data){
            
            this.derevtive[key] = []
            let direct = this.derevtive[key]
            let oldVal = data[key]

            Object.defineProperty(this.$data, key, {
                get(){
                    return oldVal
                },
                set(newVal){
                    if(newVal !== oldVal){
                        oldVal = newVal
                        // 這里數(shù)據(jù)更新了,發(fā)布消息通知視圖更新,
                        // this.derevtive里面存儲了所有的數(shù)據(jù)的全部watcher實例,在解析指令的過程中創(chuàng)建
                        direct.forEach(item=>{
                            item.updata()
                        })

                    }
                }
            })


        }
    }

    // 指令解析
    Compile(node){
        let nodes = node.children
        for(let i=0,len=nodes.length;i<len;i++){
            let nodeChild = nodes[i]
            if(nodeChild.children.length){
                this.Compile(nodeChild)
            }

            if(nodeChild.hasAttribute('v-text')){
                let attr = nodeChild.getAttribute('v-text')

                this.derevtive[attr].push(new Watcher({
                    nodeChild,
                    type: 'innerText',
                    vm: this,
                    attr: attr
                }))

            }

            if(nodeChild.hasAttribute('v-model')){
                let attr = nodeChild.getAttribute('v-model')

                this.derevtive[attr].push(new Watcher({
                    nodeChild,
                    type: 'value',
                    vm: this,
                    attr: attr
                }))

                nodeChild.addEventListener('input', ()=>{
                    this.$data[attr] = nodeChild.value
                })
            }

        }
    }

}

class Watcher {
    constructor(options){
        this.nodeChild = options.nodeChild
        this.type = options.type
        this.vm = options.vm
        this.attr = options.attr
        this.updata()
    }

    updata(){
        this.nodeChild[this.type] = this.vm.$data[this.attr]
    }
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容