百度前端技术学院---vue动态数据绑定-2

本文介绍如何使用JavaScript实现对象属性的响应式更新及监听功能。通过自定义Observer类,可以实现对对象属性的get和set操作进行拦截,并记录属性访问与修改的日志。此外,还介绍了如何在数据发生变化时触发回调函数,以便执行特定的操作。

1.如果设置新的值是一个对象的话,新设置的对象的属性是否能能继续响应 getter 和 setter

在上一步的基础上,我们直接设置data属性,是不会响应的,如:
app1.data.user = {a:1};
app1.data.user.a;
    (function(){
        window.Observer = function(data){
            this.data=data;
            this.makeObserver();
        };
        Observer.prototype.makeObserver = function(){
            for(var key in this.data){
                if(!this.data.hasOwnProperty(key))return;
                var val = this.data[key];
                if(typeof val === 'object'){
                    new Observer(val);
                }
                this.setObserver(val,key);
            };
        };
        Observer.prototype.setObserver = function(val,key){
            var that = this;
            Object.defineProperty(that.data,key,{
                enumerable: true,
                configurable: true,
                get:function(){
                    console.info("你访问了"+key);
                    return val;
                },
                set:function(newValue){
                    if(typeof newValue === 'object'){
                        new Observer(newValue);
                    };
                    console.info("你设置了"+key+",新的值为",newValue);
                    if(val === newValue)return;
                    val = newValue;
                }
            });     
        };
    })()
//在set中,通过判断newValue是否是对象,来设置新对象的属性;
var app1 = new Observer({
    user:{
        ha:1
    }
});

app1.data.user={
    name:2
};
app1.data.user.name=3;
/*
输出:
你设置了user,新的值为 Object {}
你访问了user
你设置了name,新的值为 3
*/
2.数据改变时,需要回调函数
通过原型上建立一个watchArr对象,保存监听属性和回调函数,在set触发时执行
    (function(){
        window.Observer = function(data){
            this.data=data;
            this.makeObserver();
        };
        //监听对象
        Observer.prototype.watchArr = {};
        Observer.prototype.makeObserver = function(){
            for(var key in this.data){
                if(!this.data.hasOwnProperty(key))return;
                var val = this.data[key];
                if(typeof val === 'object'){
                    new Observer(val);
                }
                this.setObserver(val,key);
            };
        };
        Observer.prototype.setObserver = function(val,key){
            var that = this;
            Object.defineProperty(that.data,key,{
                enumerable: true,
                configurable: true,
                get:function(){
                    console.info("你访问了"+key);
                    return val;
                },
                set:function(newValue){
                    if(typeof newValue === 'object'){
                        new Observer(newValue);
                    };
                    console.info("你设置了"+key+",新的值为",newValue);
                    if(val === newValue)return;
                    if(that.watchArr[key]){     
                    //如果监听对象对应key存在,则执行回调
                        for(var i = 0;i<that.watchArr[key].length;i++){     
                            that.watchArr[key][i](newValue,val);
                        }
                    }
                    val = newValue;
                }
            });     
        };
        //监听函数
        Observer.prototype.$watch = function(key,fn){
            if(!this.watchArr[key]){
                this.watchArr[key]=[];
            };      
            this.watchArr[key].push(fn);
        };
        return this;
    })()

var app1 = new Observer({
    user:{
        info:1
    },
    age:10
});
app1.data.user={
    name:2
};
 app1.$watch('name', function(name,oldname) {
         console.log(`我的名字${oldname}变了,现在已经是:${name}`)
      }).$watch('age', function(age,oldage) {
         console.log(`我的年龄${oldage}变了,现在已经是:${age}`)
      });
app1.data.user.name=3;
app1.data.age=33;
/*
输出为:
你设置了user,新的值为 Object {}
你访问了user
你设置了name,新的值为 3
我的名字2变了,现在已经是:3
你设置了age,新的值为 33
我的年龄10变了,现在已经是:33
*/

转载于:https://www.cnblogs.com/LiangHuang/p/6498333.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值