vue动态数据绑定2---响应数据变化

在动态数据绑定1的基础上,考虑传递回调函数。在实际应用中,当特定数据发生改变的时候,我们是希望做一些特定的事情的,而不是每一次都只能打印出一些信息。所以,我们需要支持传入回调函数的功能。举个例子。

let app = new Observer({
         name: 'yjm',
         age: 20
 });

 // 你需要实现 $watch 这个 API
 app1.$watch('age', function(age) {
         console.log(`我的年纪变了,现在已经是:${age}岁了`)
 });

 app1.data.age = 100; // 输出:'我的年纪变了,现在已经是100岁了'

要实现上述功能,首先要监听数据的变化,将被监听的数据对象及相应的回调函数放到一个对象events里,当数据变化之后,再从events里拿出被触发的数据对象的回调函数,并触发该回调函数,对数据的变化做出响应。

<script>
function Observer(data, events) {
    this.data = data;
    // 存放监听事件的回调
    this.events = events || {};
    this.walk(data, this.events);
}
// 遍历对象的各个属性,为其添加setter和getter
Observer.prototype.walk = function(data, events) {
    for(var key in data) {
        if(data.hasOwnProperty(key)){
            if(typeof(data[key]) == 'object'){
                new Observer(data[key], events)
            };
            this.convert(key, data[key], events);
        }
    }
}
Observer.prototype.convert = function(key, val, events) {
    var self = this;
    Object.defineProperty(this.data, key, {
        enumerable: true,
        configurable: true,
        get: function() {
            console.log('你访问了' + key);
            return val;
        },
        set: function(newVal) {
            console.log('你设置了', key, ',新的值为', newVal);
            if (newVal !== val) {
                val = newVal;
                // 触发当前key事件
                self.$emit(key, newVal); 
            }
            // 如果这个newVal是obj,继续递归调用new Observer
            if (typeof newVal === "object") { 
                return new Observer(newVal, events);
            }
        }
    })
}
// 将所监听事件及其回调函数添加到events对象
Observer.prototype.$watch = function(key, listener) {
    if(!this.events[key]){
        this.events[key] = [];
    };
    this.events[key].push(listener);
}
// 触发事件,并调用events里的相应事件的回调函数
Observer.prototype.$emit = function() {
    var key = [].shift.call(arguments);
    var data = [].slice.call(arguments);
    if(!this.events[key] || this.events[key].length < 1) return;
    this.events[key].forEach(function(listener){
        listener(data || {})
    })
}

let data={
    name: "yjm",
    address: "成都"
};

let app =new Observer(data);

app.$watch('name', function(name){
    console.log(`你的名字变了,现在是${name}`);
});
app.$watch('address', function(address){
    console.log(`你的地址改变了,现在是${address}`);
});
app.data.name = 'jmy';
</script>

相较于动态数据绑定1,实现传递回调函数主要是添加了一个事件对象events,将被监听的对象及其回调函数保存到events,在事件对象被触发的时候,调用events里保存的相应的回调函数。实现效果如下:
image

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值