您的位置:首页 > 产品设计 > UI/UE

vue动态数据绑定3--深层次数据变化逐层往上传播

2017-08-01 21:24 471 查看
基于vue动态数据绑定2,再多考虑一个问题:”深层次数据变化如何逐层往上传播”。举个例子。

let app = new Observer({
name: {
first: 'yy',
last: 'jm'
},
age: 18
});

app2.$watch('name', function (newName) {
console.log('你的姓名发生了变化')
});

app.data.name.firstName = 'hahaha';
// 输出:你的姓名发生了变化。


为了实现深层次数据变化的向上传播,需要得到被改变的数据的父级并触发相应的回调函数,然后再逐级向上触发每一层级的回调函数。实现代码如下:

<script>
function Observer(data, events, parent, parentKey){
this.data = data;
this.events = events || {};
this.parent = parent || {};
this.parentKey = parentKey || '';
this.walk(data, this.events);
}
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, key)
};
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的上级,如果有的话
var parent = self.parent;
// 保存key的上级的key值
var parentKey = self.parentKey;
// 循环寻找上级触发事件
while (parent) {
self.$emit(parentKey, newVal);
parentKey = parent.parentKey;
parent = parent.parent;
}
//触发当前key事件
self.$emit(key, newVal);
}
// 如果这个newVal是obj,继续递归调用new Observer
if (typeof newVal === "object") {
return new Observer(newVal, events, this, key);
}
}
})
}

Observer.prototype.$watch = function(key, listener) {
if(!this.events[key]){
this.events[key] = [];
};
this.events[key].push(listener);
}

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 || {})
})
}
var data = {
user: {
name: {
first: {
y: "y"
},
last: "jm"
},
age: 18
},
address: "成都"
}

let app = new Observer(data);

app.$watch('user', function() {
console.log('你改变了user');
});
app.$watch('name', function(){
console.log('你改变了name');
});
app.$watch('first', function(){
console.log('你改变了first');
});
app.$watch('y', function(y){
console.log(`你改变了y, 现在是${y}`);
});
app.$watch('age', function(age){
console.log(`你的age改变了,现在是${age}`);
});
app.$watch('address', function(address){
console.log(`你的address改变了,现在是${address}`);
});
app.data.user.age = 20;
</script>


在vue数据绑定2的基础上,增加了this.parent、提示。parentKey用于得到相应元素的上级,然后再得到上级的上级… 。

效果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  vue