美文网首页
数据双向绑定的原理分析

数据双向绑定的原理分析

作者: 祝家庄打烊 | 来源:发表于2020-02-18 12:54 被阅读0次

模板编译

1、所有的DOM操作,都放到内存fragment中执行(创建fragment内存空间,把所有的子元素都移动到fragment中包裹,操作完DOM元素后,在把fragment移动到根节点上)。

function compile(el,data){
    var fragment = document.createDocumentFragment();
    var first = null;
    while(first=el.firstChild){
        fragment.appendChild(first);
    }
    renderDom(fragment);
    el.appendChild(fragment);
}

2、HTML中存在v-html和{{}}内容编译成对应的数据(遍历fragment子元素,判断是元素节点还是文本节点,文本节点去掉{{}}找到对应的数据来源,在给相应的元素赋值)
区分DOM节点

function renderDom(fragment){
    var _that = this;
    Array.from(fragment.childNodes).forEach(function(item){
        if(item.nodeType==1){
            //元素节点
            renderElement(item);
            if(item.childNodes.length>0) renderDom(item);
        }else{
            //文本节点
            renderText(item)
        };
    })
}

遍历元素节点的属性值,找到对应的v-

function renderElement(dom){
    Array.from(dom.attributes).forEach(function(attr){
        if(attr.name=="v-html"||attr.name=="v-text"||attr.name=="v-model"){
            eleRender(attr.value,dom);
        }
    })
}

元素节点赋值

function eleRender(value,dom){
    if(dom.tagName.toLocaleLowerCase()=="input"){
        dom.value = compileData(value);
    }else{
        dom.innerHTML = compileData(value);
    }
    
}

文本节点赋值

function renderText(text){
    var reg = /\{\{([^}]+)\}\}/;
    text.textContent.replace(reg,function(){
        new Watch(arguments[1],function(newValue){
            text.textContent = newValue;
        })
        text.textContent = compileData(arguments[1]);
    })
}

数据劫持

当数据data发生改变的时候,重新编译模板。(利用的是Object.defineProperty监听数据变化,watch方法对每个元素进行监听,发布订阅者模式订阅watch对象,发布watch对象中update方法)
1、Object.defineProperty监听数据变化(是对象上的每个属性进行监听,而且要监听到数据的最底层)

function observer($data){
    if(!$data || typeof($data)!="object"){
        return false;
    }
    for(var key in $data){
        defineWatch($data,key,$data[key])
    }
}
function defineWatch($data,key,value){
    observer(value);
    //监听对象中某个属性的变化
    var subScript = new Subscribe();
    Object.defineProperty($data, key, {
        enumerable: true,
        configurable: true,
        get:function(){
            subScript.order(Subscribe.dep);
            return value;
        },
        set:function(newValue){
            value=newValue;
            subScript.push();
        }
    })
}

2、定义watch方法,对每个元素进行绑定,当监听到的数据改变时,触发watch方法,对元素重新赋值

function Watch(explor,callback){
    Subscribe.dep = this;
    this.oldValue = compileData(explor);
    Subscribe.dep = null;
    this.update = function(){
        var newValue = compileData(explor);
        console.log("newValue",newValue)
        if(this.oldValue!=newValue){
            callback(newValue)
        }
    }
}
image.png

3、定义发布订阅者模式,当获取数据的时候,表明元素正在进行赋值操作,这时,需要订阅watch对象,当改变数据的时候,表明赋值完成,这时,需要发布watch对象上的update方法,对监听到元素进行赋值操作。

function Subscribe(){
    this.store = [];
    this.order = function(watch){
        this.store.push(watch);
    }
    this.push = function(){
        if(this.store.length==0) return false;
        this.store.forEach(function(item){
            item && item.update()
        })
    }
}

项目案例

相关文章

  • 深入Vue响应式原理

    1.Vue的双向数据绑定 参考 vue的双向绑定原理及实现Vue双向绑定的实现原理Object.definepro...

  • vue 双向数据绑定

    Vue实现数据双向绑定的原理:Object.defineProperty()vue实现数据双向绑定主要是:采用数据...

  • 【转】JavaScript的观察者模式(Vue双向绑定原理)

    关于Vue实现数据双向绑定的原理,请点击:Vue实现数据双向绑定的原理原文链接:JavaScript设计模式之观察...

  • 前端理论面试--VUE

    vue双向绑定的原理(详细链接) VUE实现双向数据绑定的原理就是利用了 Object.definePropert...

  • Vue实现数据双向绑定的原理

    Vue实现数据双向绑定的原理:Object.defineProperty() vue实现数据双向绑定主要是:采用数...

  • vue面试知识点

    vue 数据双向绑定原理 vue实现数据双向绑定原理主要是:采用数据劫持结合发布订阅设计模式的方式,通过对data...

  • 数据双向绑定的原理分析

    模板编译 1、所有的DOM操作,都放到内存fragment中执行(创建fragment内存空间,把所有的子元素都移...

  • vue 面试汇总(更新中...)

    1.说说对双向绑定的理解 1.1、双向绑定的原理是什么 我们都知道Vue是数据双向绑定的框架,双向绑定由三个重要部...

  • Vue双向数据绑定原理

    剖析Vue实现原理 - 如何实现双向绑定mvvm 本文能帮你做什么?1、了解vue的双向数据绑定原理以及核心代码模...

  • 关于双向绑定的问题

    剖析Vue实现原理 - 如何实现双向绑定mvvm 本文能帮你做什么?1、了解vue的双向数据绑定原理以及核心代码模...

网友评论

      本文标题:数据双向绑定的原理分析

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