zoukankan      html  css  js  c++  java
  • vue 缩水版 双向绑定

    function Observer(obj, key, value){
        var dep = new Dep();
        if (Object.prototype.toString.call(value) == '[object Object]') {
            Object.keys(value).forEach(function(key){
                new Observer(value,key,value[key])
            })
        };
    
        Object.defineProperty(obj, key, {
            enumerable: true,
            configurable: true,
            get: function(){
                if (Dep.target) {
                    dep.addSub(Dep.target);
                };
                return value;
            },
            set: function(newVal){
                value = newVal;
                dep.notify();
            }
        })
    }
     
    
    function Watcher(fn){
        this.update = function(){
            Dep.target = this;
            fn();
            Dep.target = null;
        }
        this.update();
    }
    
    
    function Dep(){
        this.subs = [];
    
        this.addSub = function (watcher) {
            this.subs.push(watcher);
        }
    
        this.notify = function(){
            this.subs.forEach(function(watcher){
                watcher.update();
            });
        }
    }
      
    
    <div id="test"></div>
     
        var obj = {
            a: 1,
            b: 2,
            c: 3
        }
        Object.keys(obj).forEach(function(key){
            new Observer(obj, key, obj[key])
        });
        new Watcher(function(){
            document.querySelector("#test").innerHTML = obj.a;
        })
     
    function Observer(obj, key, value){
           //这里会生成4个dep对象; 分别对应的是属性 a , b, b.b1, c 的派系; 如果一个数据total的计算需要 a的值, 就在第一个dep中添加第三个watcher,
         // 这样obj.a改变, 就会触发第三个watcher的回调, 来更新页面; obj.c的改变也会触发第三个watcher
    var dep = new Dep(); if (Object.prototype.toString.call(value) == '[object Object]') { Object.keys(value).forEach(function(key){ new Observer(value,key,value[key]) }) }; Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function(){ if (Dep.target) { dep.addSub(Dep.target); }; return value; }, set: function(newVal){ value = newVal; dep.notify(); } }) } function Watcher(fn){ this.update = function(){ Dep.target = this; this.callback(); Dep.target = null; } this.callback = fn; this.update(); } function Dep(){ this.subs = []; this.addSub = function (watcher) { this.subs.push(watcher); } this.notify = function(){ this.subs.forEach(function(watcher){ watcher.update(); }); } } var obj = { a: 1, b: { b1: 33 }, c: 3 } Object.keys(obj).forEach(function(key){ new Observer(obj, key, obj[key]) }); new Watcher(function(){ document.querySelector("#app").innerHTML = obj.a; //执行到这里, 有一个取值的操作, 会进入obj对象a属性的get方法 }) new Watcher(function(){ document.querySelector("#test").innerHTML = obj.b.b1; //执行到这里, 也有取值的操作, 先取obj.b, 第一次进入b属性的get方法, 第二次进入b1的get方法 })

        
         new Watcher(function(){
                document.querySelector("#test").innerHTML = obj.a + obj.c;  
            })

      
         obj.a = 100; //进入ojb属性a的set方法
    function Observer(obj, key, value){
           //这里注册被订阅主体
                var dep = new Dep();
                if (Object.prototype.toString.call(value) == '[object Object]') {
                    Object.keys(value).forEach(function(key){
                        new Observer(value,key,value[key])
                    })
                };
    
                Object.defineProperty(obj, key, {
                    enumerable: true,
                    configurable: true,
                    get: function(){
                        if (Dep.target) {
                            dep.addSub(Dep.target);
                        };
                        return value;
                    },
                    set: function(newVal){
                        value = newVal;
                        dep.notify();
                    }
                })
            }
             
    
            //Watcher, 其实就是订阅者, 这个函数是面向页面更新操作
            function Watcher(fn){
                this.update = function(firstDef){                
                    this.callback();                
                }
                this.callback = fn;  //这里其实可以放入多个回调,一个watcher存放多个回调函数, 
    
                Dep.target = this;
                this.callback(); //先执行一次,来触发obj.a 的get方法; 从而a的dep收集这个watcher,    并且给页面赋值;
                Dep.target = null;
            }
    
    
            //这是发布订阅系统, 这个东西是面向对象obj的属性的。 每个属性再defineProperty的时候, 新增了一个dep, 它可以被一个页面多个地方更新依赖,使用;
          
            function Dep(){
                this.subs = [];
    
                this.addSub = function (watcher) {
                    this.subs.push(watcher);
                }
    
                this.notify = function(){
                    this.subs.forEach(function(watcher){
                        watcher.update();
                    });
                }
            }
         
             
            var obj = {
                a: 1,
                b: {
                    b1: 33
                },
                c: 3
            }
    
            Object.keys(obj).forEach(function(key){
                new Observer(obj, key, obj[key])
            });
    
            new Watcher(function(){
                //这里就是收集依赖的过程, obj.a会触发get方法, 这样a属性的dep就添加了这个函数为回调的watcher, 作为依赖一
                document.querySelector("#app").innerHTML = obj.a;
            })
    
            new Watcher(function(){
                //这里再次收集依赖, obj.a会触发get方法, 这样a属性的dep就 又添加 添加了一个函数watcher, 作为依赖二, 这样
                // a属性的dep就有了两个依赖, 在设置a属性的时候, 就会触发这两个依赖函数.
                document.querySelector("#test").innerHTML = obj.a;
            })
    
            new Watcher(function(){
                document.querySelector("#test").innerHTML = obj.a + obj.c;
            })
    
            obj.a = 3;
    function Observer(obj, key, value){
           //这里注册被订阅主体
    var dep = new Dep(); if (Object.prototype.toString.call(value) == '[object Object]') { Object.keys(value).forEach(function(key){ new Observer(value,key,value[key]) }) }; Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function(){ if (Dep.target) { dep.addSub(Dep.target); }; return value; }, set: function(newVal){ value = newVal; dep.notify(); } }) } //Watcher, 其实就是订阅者, 这个函数是面向页面更新操作 function Watcher(fn){ this.update = function(firstDef){ this.callback(); } this.callback = fn; //这里其实可以放入多个回调,一个watcher存放多个回调函数, Dep.target = this; this.callback(); //先执行一次,来触发obj.a 的get方法; 从而a的dep收集这个watcher, 并且给页面赋值; Dep.target = null; } //这是发布订阅系统, 这个东西是面向对象obj的属性的。 每个属性再defineProperty的时候, 新增了一个dep, 它可以被一个页面多个地方更新依赖,使用; function Dep(){ this.subs = []; this.addSub = function (watcher) { this.subs.push(watcher); } this.notify = function(){ this.subs.forEach(function(watcher){ watcher.update(); }); } } var obj = { a: 1, b: { b1: 33 }, c: 3 } Object.keys(obj).forEach(function(key){ new Observer(obj, key, obj[key]) }); new Watcher(function(){ document.querySelector("#app").innerHTML = obj.a; }) new Watcher(function(){ document.querySelector("#test").innerHTML = obj.b.b1; }) new Watcher(function(){ document.querySelector("#test").innerHTML = obj.a + obj.c; }) obj.a = 3;
    function Observer(obj, key, value){
                var dep = new Dep();
                if (Object.prototype.toString.call(value) == '[object Object]') {
                    Object.keys(value).forEach(function(key){
                        new Observer(value,key,value[key])
                    })
                };
    
                Object.defineProperty(obj, key, {
                    enumerable: true,
                    configurable: true,
                    get: function(){
                        if (Dep.target) {
                            dep.addSub(Dep.target);
                        };
                        return value;
                    },
                    set: function(newVal){
                        value = newVal;
                        dep.notify();
                    }
                })
            }
             
    
            function Watcher(fn){
                this.update = function(firstDef){
                    if(firstDef){
                        Dep.target = this;
                    }
                    
                    this.callback();
                    Dep.target = null;
                }
                this.callback = fn;
                this.update(true);
            }
    
    
            function Dep(){
                this.subs = [];
    
                this.addSub = function (watcher) {
                    this.subs.push(watcher);
                }
    
                this.notify = function(){
                    this.subs.forEach(function(watcher){
                        watcher.update();
                    });
                }
            }
         
             
            var obj = {
                a: 1,
                b: {
                    b1: 33
                },
                c: 3
            }
    
            Object.keys(obj).forEach(function(key){
                new Observer(obj, key, obj[key])
            });
    
            new Watcher(function(){
                document.querySelector("#app").innerHTML = obj.a;
            })
    
            new Watcher(function(){
                document.querySelector("#test").innerHTML = obj.b.b1;
            })
    
            new Watcher(function(){
                document.querySelector("#test").innerHTML = obj.a + obj.c;
            })
    
            obj.a = 3;
  • 相关阅读:
    【转】很全的TeeChart for .NET中文教程
    对比两个flash金融图表Stock Chart vs AnyStock
    FusionCharts实例大全
    [译]金融图表AnyStock的9个使用技巧
    看懂SqlServer查询计划
    怎样修改MySQL的默认编码
    VS2003+自带水晶报表的打包部署(CS方式)
    ADO.NET 连接池理解
    临时表 & 表变量
    Eclipse 快捷键介绍
  • 原文地址:https://www.cnblogs.com/dhsz/p/8435956.html
Copyright © 2011-2022 走看看