Vue源码分析之delete

·  阅读 73

这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

前言

上篇看了Vue的实例方法$set主要用来在给对象数组添加数据项时,将添加项转化为响应式数据。而删除对象中的某一项官方推荐用$delete方法来实现,这篇文就来看下delete操作是怎么实现的??

Vue.delete

官方在介绍Vue.delete时,说该方法主要用来处理Vue不能检测到的属性删除情况,却又要大家少用。

image.png

$set方法定义在src/core/instance.state.js中:

export function stateMixin (Vue: Class<Component>) {
  ...
  Vue.prototype.$delete = del
  ...
}
复制代码

vm.$delete

与$set类似,Vue的实例方法$delete也是全局API Vue.delete的别名。

image.png

定义在src/core/instance.state.js中:

export function stateMixin (Vue: Class<Component>) {
  ...
  Vue.prototype.$delete = del
  ...
}
复制代码

内部都是指向了del方法,接下来看下这个方法:

del

del方法定义在src/core/observer/index.js中

export function del (target: Array<any> | Object, key: any) {
  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__
  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]
  if (!ob) {
    return
  }
  ob.dep.notify()
}
复制代码
  • 跟set一样,先判断目标对象本身是否合法。

  • 如果目标对象是数组且下标合法,则调用splice直接删除(其实很少会对数组用delete方法吧,因为可以直接调用splice去触发更新,没必要再绕一层),然后返回。

  • 接下来判断目标对象是不是Vue实例的根对象或者Vue实例,如果是直接返回。

  • 接下来判断是不是key属性本身就不在目标对象中,如果不在直接返回。

  • key在目标对象中,则调用delete方法删除。

  • 判断目标对象本身是否是响应式对象,如果不是则直接返回。如果是,则调用notify触发更新。

分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改