Appearance
六、$delete
功能
- 删除对象的属性。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到属性被删除的限制,但是你应该很少会使用它。
- 注意:目标对象不能是一个 Vue 实例或 Vue 实例的根数据对象($data)。
使用
之前的页面中使用,先删除obj中的title元素,可以看到删除元素会触发更新视图的操作.同样删除数组的第一个元素,也触发了视图的更新.
源码分析
定义的位置和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是一个方法
js
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()
}