JS没有提供方法来侦测到一个属性被删除了, 因此如果我们通过delete删除一个属性, Vue是侦测不到的, 因此不会触发数据响应式。分析VUE.$delete()实现过程
export function del(target: Array<any> | Object, key: any) {
// 不允许删除一个原始数据类型, 或者undefined, null
if (
process.env.NODE_ENV !== "production" &&
(isUndef(target) || isPrimitive(target)) //原始的
) {
warn(
`Cannot delete reactive property on undefined, null, or primitive-原始的 value: ${(target: any)}`
);
}
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.splice(key, 1);
return;
}
const ob = (target: any).__ob__;
// target._isVue: 不允许删除Vue实例对象上的属性
// (ob && ob.vmCount): 不允许删除根数据对象的属性,触发不了响应
if (target._isVue || (ob && ob.vmCount)) {
process.env.NODE_ENV !== "production" &&
warn(
"Avoid deleting properties on a Vue instance or its root $data " +
"- just set it to null."
);
return;
}
// 如果属性压根不在对象上, 什么都不做处理
if (!hasOwn(target, key)) {
return;
}
delete target[key];
// 如果ob不存在, 说明target本身不是响应式数据,
if (!ob) {
return;
}
// 通知依赖更新
ob.dep.notify();
}