vue set实现原理
Vue.set 的实现原理
Vue.set 是 Vue.js 提供的一个全局 API,用于向响应式对象添加新属性并确保新属性也是响应式的。其核心原理基于 Vue 的响应式系统。
响应式系统的核心
Vue 的响应式系统通过 Object.defineProperty 或 Proxy(Vue 3)实现数据劫持。当对象被初始化为响应式时,Vue 会递归遍历对象的属性,将其转换为 getter/setter,从而在属性被访问或修改时触发依赖更新。
Vue.set 的作用场景
直接通过普通方式为对象添加新属性(如 obj.newProperty = value)时,新属性不是响应式的,因为 Vue 无法检测到这种动态添加。Vue.set 解决了这一问题,确保新属性也被 Vue 的响应式系统追踪。

实现原理细节
-
检查目标对象是否为响应式
Vue.set 首先检查目标对象是否是 Vue 实例或响应式对象。如果不是,直接赋值并返回。 -
处理数组情况
如果目标是数组,Vue.set 会调用数组的 splice 方法(已被 Vue 重写为响应式方法)添加或修改元素,触发依赖更新。
-
处理对象情况
对于对象,Vue.set 会调用 defineReactive 方法将新属性转换为响应式属性,并手动触发依赖通知(dep.notify)。
源码简化示例
以下是 Vue 2.x 中 Vue.set 的简化实现逻辑:
function set(target, key, value) {
// 检查是否为数组
if (Array.isArray(target)) {
target.length = Math.max(target.length, key);
target.splice(key, 1, value);
return value;
}
// 检查是否为已有响应式属性
if (key in target && !(key in Object.prototype)) {
target[key] = value;
return value;
}
// 获取对象的 __ob__ 属性(Observer 实例)
const ob = target.__ob__;
if (!ob) {
target[key] = value;
return value;
}
// 将新属性转换为响应式
defineReactive(ob.value, key, value);
ob.dep.notify(); // 手动触发依赖更新
return value;
}
Vue 3 的变化
在 Vue 3 中,由于使用 Proxy 实现响应式,Vue.set 的等效操作是直接赋值,因为 Proxy 可以拦截动态添加的属性。但为了兼容性,仍提供了类似 API(如 Vue.set 或 reactive 的用法)。
使用场景建议
- 动态添加响应式属性时优先使用 Vue.set。
- 对于已知结构的对象,应在 data 中预先声明所有属性以避免动态添加。
- Vue 3 中通常不需要显式调用 Vue.set,直接赋值即可。






