六、$delete

Vue

# 功能

  • 删除对象的属性。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它。
  • 注意:目标对象不能是一个 Vue 实例或 Vue 实例的根数据对象($data)。

# 使用

之前的页面中使用,先删除obj中的title元素,可以看到删除元素会触发更新视图的操作.同样删除数组的第一个元素,也触发了视图的更新.

image

# 源码分析

定义的位置和set方法一样

  • Vue.delete()
    • global-api/index.js
    • 里面的del方法是在observer/index.js中定义(与响应式相关)
  • vm.$delete()
    • instance/index.js
    • 里面的stateMixin函数在instance/state.js
    • 里面的Vue.prototype.$delete也是在observer/index.js中定义,与静态方法delete是一个方法
export function del (target: Array<any> | Object, key: any) {
  // 判断当前target是否是undefined或者是原始值,如果是就发出警告
  if (process.env.NODE_ENV !== 'production' &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(`Cannot delete reactive property on undefined, null, or primitive value: ${(target: any)}`)
  }
  // 判断target是否是数组,索引是否有效
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    // 使用splice方法修改,不传第三个方法就是删除指定元素
    // 里面会去更新通知
    target.splice(key, 1)
    return
  }
  // 如果target是对象就会获取ob对象
  const ob = (target: any).__ob__
  // 判断是不是vue是和$data对象,是就会发送警告
  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
  }
  // 判断当前对象中是否有key属性,key不能是继承来的,如果没有直接返回
  if (!hasOwn(target, key)) {
    return
  }
  // 删除属性
  delete target[key]
  // 如果ob不存在,说明不是响应式数据,直接返回
  if (!ob) {
    return
  }
  // 发送通知更新视图
  ob.dep.notify()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 调试的内容和$set一样

更新时间: 2022-01-13 21:13