为什么需要Vue.delete()

88 阅读1分钟

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();
}