欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VUE - vue2.0与vue3.0双向数据绑定的实现原理及区别

程序员文章站 2022-07-12 21:56:52
...

vue2.0实现双向数据绑定原理

vue2.0中通过利用Object.defineProperty方法监听属性的get和set方法来实现对数据的双向绑定,看如下示例:

<!DOCTYPE html>
<html>
<head>
<style> 

</style>
</head>
<body>
Name: <span id="txtName"></span>
<br />
<input id='inpName' type="text">
<script>
    let obj = {name: ''};
    let newObj = JSON.parse(JSON.stringify(obj));
    Object.defineProperty(obj, 'name', {
        get: function(){
            return newObj.name;
        }
        set: function(val){
            if(val === obj.name) return;            
            newObj.name = val;
            observer();
        }
    });

    function observer(){
        txtName.innerHTML = obj.name;
        inpName.value = obj.name; 
    }

    inpName.oninput = function(){
        obj.name = this.value;
    }

    setTimeout(() => {
        obj.name = 'Hello world';
    }, 2000);
</script>
</body>
</html>

上面代码中利用Object.defineProperty方法去监听obj对象的name属性的get和set方法。这里需要注意的是:需要对obj对象进行克隆,而在监听函数中的赋值取值操作均操作的是克隆后的对象newObj(避免死循环),因为如果操作原对象obj,这样在get方法中会读取name属性,而只要涉及到读取name属性就会被defineProperty函数监听,这样就造成了死循环。

当对obj的name属性设置值时,会触发set方法,将新值赋值给newObj的name属性同时将新值绑定到视图上,实现属性变视图变。另外需要绑定视图控件的oninput事件,当文本框中的内容发生变化时将新值赋值给obj的name属性同时又会触发监听函数,从而实现了数据的双向绑定。

vue3.0实现双向数据绑定原理

<!DOCTYPE html>
<html>
<head>
<style> 

</style>
</head>
<body>
Name: <span id="txtName"></span>
<br />
<input id='inpName' type="text">
<script>
    let obj = {name: ''};
    obj = new Proxy(obj, {
        get(target, prop){
            return target[prop];
        }
        
        set(target, prop, value){
            target[prop] = value;
            observer();
        }
    });
    function observer(){
        txtName.innerHTML = obj.name;
        inpName.value = obj.name; 
    }

    inpName.oninput = function(){
        obj.name = this.value;
    }

    setTimeout(() => {
        obj.name = 'Hello world';
    }, 2000);
</script>
</body>
</html>

3.0中的绑定原理与2.0中的原理基本一致都是通过监听属性值来改变视图值,然后通过视图的input事件而改变属性值。不同都是这里使用了ES6中的新语法Proxy来实现数据监听。

二者的区别

  • 2.0中使用的是Object.defineProperty实现对属性的监听。缺点是一定要克隆一个新的对象进行操作,否则就会造成死循环。第二个缺点是如果有多个属性,那么就要定义多个Object.defineProperty去分别监听每一个属性。
  • 3.0中使用了ES6中的新语法,用到了Proxy去实现监听,这样省去了克隆对象的步骤,同时不管有多少个属性只需要定义一次Proxy就可以实现多对象的监听,不同分别定义。