// 观察一个vue 的defineProperty
// 只针对对象 数组没有使用defineProperty的
let arrayProto = Array.prototype;
let proto = Object.create(arrayProto);
["push", "shift", "splice"].forEach((method) => {
proto[method] = function (...args) {
let inserted;
switch (method) {
case "push":
case "unshift":
inserted = args;
break;
case "splice": //数组的splice 只有传递3个参数才有追效果
inserted = args.slice(2);
default:
break;
}
console.log("更新视图Array");
ArrayObserver(inserted);
arrayProto[method].call(this, ...args);
};
});
function ArrayObserver(obj) {
for (let i = 0; i < obj.length; i++) {
const item = obj[i];
observer(item); //是对象会被defineReactive
}
}
function observer(obj) {
if (typeof obj !== "object" || obj == null) {
return obj;
}
if (Array.isArray(obj)) {
// 处理数组格式
Object.setPrototypeOf(obj, proto);
ArrayObserver(obj);
} else {
//处理对象
for (const key in obj) {
defineReactive(obj, key, obj[key]);
}
}
}
function defineReactive(obj, key, value) {
observer(value);
Object.defineProperty(obj, key, {
get() {
return value;
},
set(newValue) {
if (value !== newValue) {
observer(value);
value = newValue;
console.log("更新视图Object");
}
},
});
}
let data = {
name: "zf",
arr: [1, 2, 3, { age: 1 }],
};
observer(data);
data.arr[3].age = "88";
data.arr.push({ hh: 66 });
vue 视图更新原理核心代码
最新推荐文章于 2022-12-04 19:22:53 发布