- vue2.0 通过Object.defineProperty
- vue3.0 通过Proxy
实现原理
const arrProto = Array.prototype;
const newArrProto = Object.create(arrProto);
['push', 'unshift', 'splice', 'reverse', 'sort', 'shift', 'pop'].forEach(method => {
newArrProto[method] = function(...args) {
let inserted;
switch (method) {
case 'push':
case 'unshift':
{
inserted = args;
break;
}
case 'splice':
{
inserted = args.slice(2);
}
default:
break;
}
observerArray(inserted);
arrProto[method].call(this, ...args);
};
});
function observer(obj) {
if (typeof obj !== 'object' || obj == null)
return obj;
if (Array.isArray(obj)) {
Object.setPrototypeOf(obj, newArrProto);
observerArray(obj);
} else {
for (let i in obj) {
let item = obj[i];
defineProperty(obj, i, item);
}
}
}
function defineProperty(obj, key, value) {
observer(value);
Object.defineProperty(obj, key, {
get() {
return value;
},
set(newVal) {
if (newVal != value) {
observer(newVal);
value = newVal;
update();
}
},
})
}
function observerArray(obj) {
for (let item of obj) {
observer(item);
}
}
function update() {
console.log('视图更新');
}
简单对象
对象值也是对象
对象设置值的时候也有可能是对象
对象是数组
数组成员是对象会被监控
数组通过push,unshift,splice添加的对象也能监控到
let obj = [];
observer(obj);
obj.push({ name: 'jj' });
obj[0].name = 11;