主要使用场景,响应式对象上新增 property 时 vue无法探测到新增的 property, 向vue对象中添加一个 property 且刷新视图
export function set(target: Array<any> | Object, key: any, val: any): any {
// 开发环境 且 null | string | number | symbol | boolean 提示
if (
process.env.NODE_ENV !== "production" &&
(isUndef(target) || isPrimitive(target))
) {
warn(
`Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`
);
}
// 当 target 为数组 且 key 为有效 key 的时候
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key);
// 替换对应的值 并返回
target.splice(key, 1, val);
return val;
}
// 当 key 存在 target 的属性中
if (key in target && !(key in Object.prototype)) {
// 替换对应的值 并返回
target[key] = val;
return val;
}
// 是否 含有对应的 ob属性
const ob = (target: any).__ob__;
// 判断是否为 vue实例 或者 存在 ob 对象 且 含有 vmCount 属性
if (target._isVue || (ob && ob.vmCount)) {
process.env.NODE_ENV !== "production" &&
warn(
"Avoid adding reactive properties to a Vue instance or its root $data " +
"at runtime - declare it upfront in the data option."
);
return val;
}
// 非响应式对象 直接返回
if (!ob) {
target[key] = val;
return val;
}
// 增加对应 key 的响应事件
defineReactive(ob.value, key, val);
// 推送对应的订阅消息
ob.dep.notify();
// 返回结果
return val;
}
总结:
- 数组,替换key对应的val并返回最新结果
- 对象:
- key存在对象的属性上时,替换key对应的val并返回最新结果
- vue实例 或者 存在vmCount属性时,直接返回val
- 非响应式对象时,直接返回val
- 响应式对象,且key不存在prototype上时,增加对应的事件,返回对应的val
网友评论