学习笔记Vue(三) —— 双向数据绑定机制(与angular对比)

一、Angular中的双向数据绑定(脏检查机制):

AngularJs 为 scope 模型上设置了一个 监听队列,用来监听数据变化并更新 view 。每次绑定一个东西到 view(html) 上时 AngularJs 就会往 $watch 队列里插入一条 $watch,用来检测它监视的 model 里是否有变化的东西。当浏览器接收到可以被 angular context 处理的事件时,$digest 循环就会触发。$digest 会遍历所有的 $watch。从而更新DOM。

$watch

这有点类似于我们的观察者模式,在当前作用域 s c o p e 下 , 我 们 创 建 一 个 监 控 器 scope下,我们创建一个监控器 scopewatchers和一个监听器 w a t c h , watch, watchwatchers 负责管理所有的 w a t c h , 当 我 们 每 次 绑 定 到 U I 上 的 时 候 就 自 动 创 建 一 个 watch,当我们每次绑定到UI上的时候就自动创建一个 watchUIwatch,并把它放到 $watchers。

app.controller('MainCtrl', function($scope) {
  $scope.Hello = "Hello";
  $scope.world = "World";
});
<div>{{Hello}}</div>

这里,即便我们在 s c o p e 上 添 加 了 两 个 变 量 , 但 是 只 有 一 个 scope上添加了两个变量,但是只有一个 scopescope.Hello绑定在了UI上,因此在这里只生成了一个$watch

$digest

当浏览器接收到可以被angular context处理的事件时, d i g e s t 循 环 就 会 触 发 。 digest循环就会触发。 digestdigest将会遍历我们的 w a t c h , 如 果 watch,如果 watchwatch没有变化,这个循环检测就将停止,如果有至少一个更新过,这个循环就会再次触发,直到所有的$watch都没有变化。这样就能够保证每个model都已经不会再变化。这就是脏检查(Dirty Checking)机制

model修改一次至少要触发两次循环检查,第一次发现有 $watch 修改,再循环一次,发现无修改了才停止。

Angular中的双向数据绑定内容引用来自:
作者:Nickyzhang
链接:https://www.jianshu.com/p/ad0c48810bf1
来源:简书

二、Vue中的双向数据绑定(数据劫持)

Vue双向数据绑定的核心是使用Object.defineProperty(),劫持各个属性的getter和setter,在数据模型变化的时候,发布消息给订阅者(绑定了数据模型的DOM元素),触发相应的监听回调。
数据劫持-Observer:

<body>
    <input type="text" id="demo"/>
    <div id="show"></div>
    <script>
        var odiv = document.getElementById('show');
        var oinput = document.getElementById('demo');
        var oData = {
            valueObj: {
                value: 'grandma',
                name: 'zhang'
            }
        };
        
        oinput.oninput = function(){
            oData.valueObj.value = this.value;
        }
        function upDate (){
            odiv.innerText = oData.valueObj.value;
        }

        upDate();

        //监控对象的某个属性是否发生改变
        function Observer (data){
            if(!data || typeof data != 'object'){
                return data;
            }

            // for(var prop in data){

            // }
            Object.keys(data).forEach(function(key){
                definedRective(data, key, data[key]);
            });
        }

        function definedRective(data, key, val){
            Observer(val);
            Object.defineProperty(data, key,{
                get (){
                    return val;
                },
                set (newValue) {
                    if(newValue == val){
                        return;
                    }
                    upDate();
                }
            });
        };
        Observer(oData);
        oData.valueObj.value = 'haha';
    </script>
</body>

你可能感兴趣的:(Vue学习)