vue动态数据绑定2---响应数据变化
动态数据绑定1的基础上,考虑传递回调函数。在实际应用中,当特定数据发生改变的时候,我们是希望做一些特定的事情的,而不是每一次都只能打印出一些信息。所以,我们需要支持传入回调函数的功能。举个例子。let app = new Observer({name: 'yjm',age: 20}); // 你需要实现 $watch 这个 APIapp1.$watch
·
在动态数据绑定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里保存的相应的回调函数。实现效果如下:
更多推荐
已为社区贡献1条内容
所有评论(0)