揭开 Vue $set 神秘面纱,一探源码背后的奥秘
2023-12-25 15:48:24
在 Vue.js 的数据响应式系统中,set 扮演着重要的角色。它允许我们在运行时动态地向响应式对象添加或修改属性,并确保这些更改能够被 Vue.js 正确地追踪和更新。那么,set 的内部机制是什么样的呢?让我们通过源码解析来一探究竟。
第一部分:isUndef 和 isPrimitive 方法
首先,我们来看看 isUndef 和 isPrimitive 这两个方法。从名字就可以看出,isUndef 是判断 target 是否等于 undefined,而 isPrimitive 则是判断 target 是否属于原始值类型(string、number、boolean 等)。
const isUndef = (v) => v === undefined;
const isPrimitive = (value) => {
return (
typeof value === "string" ||
typeof value === "number" ||
typeof value === "boolean" ||
typeof value === "symbol"
);
};
第二部分:Vue.set 的实现
接下来,我们来看看 Vue.set 的实现。
export function set(target, key, val) {
if (isUndef(target) || isPrimitive(target)) {
throw new TypeError(
"Cannot set reactive property on undefined, null, or primitive value: " +
target
);
}
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key);
target[key] = val;
return val;
}
const oldVal = target[key];
if (oldVal !== val) {
target[key] = val;
Vue.notify(target, key, val, oldVal);
}
return val;
}
从代码中可以看出,Vue.set 的实现相对简单。首先,它会检查 target 是否是 undefined、null 或原始值类型。如果是,则抛出 TypeError 异常,因为这些类型的值是不可变的,无法设置响应式属性。
接下来,它会检查 target 是否是数组并且 key 是有效的数组索引。如果是,则会将 target 的长度设置为 Math.max(target.length, key),并设置 target[key] 的值为 val。
最后,如果 target[key] 的值与 val 不同,则会将 target[key] 的值更新为 val,并通知 Vue.js 进行更新。
总结
通过对 Vue.set 源码的解析,我们了解到了 set 的内部机制以及它在 Vue.js 中的作用。set 允许我们在运行时动态地向响应式对象添加或修改属性,并确保这些更改能够被 Vue.js 正确地追踪和更新。
希望这篇文章能够帮助您更好地理解 Vue.js 的数据响应式系统。如果您还有其他问题,欢迎留言讨论。