vue set实现原理
Vue.set 的实现原理
Vue.set 是 Vue.js 提供的一个全局 API,用于向响应式对象添加新属性并确保其也是响应式的。其核心原理基于 Vue 的响应式系统实现。

响应式系统基础
Vue 的响应式系统通过 Object.defineProperty 或 Proxy(Vue 3)拦截对象的属性访问和修改。当初始化一个 Vue 实例时,会递归遍历 data 对象的所有属性,将其转换为 getter/setter。

对于数组,Vue 通过重写数组的变异方法(如 push、pop 等)来实现响应式。
Vue.set 的作用场景
- 对象属性动态添加:直接给对象添加新属性时,由于属性未被初始化时的 getter/setter 拦截,无法触发视图更新。
- 数组索引修改:直接通过索引修改数组元素(如 arr[0] = newValue)无法触发响应式更新。
源码实现分析
Vue.set 的核心逻辑如下:
function set (target, key, val) {
// 检查目标是否为响应式对象
if (process.env.NODE_ENV !== 'production' &&
(isUndef(target) || isPrimitive(target))
) {
warn('Cannot set reactive property on undefined, null, or primitive value')
}
// 处理数组情况
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key)
target.splice(key, 1, val)
return val
}
// 处理对象已有属性
if (key in target && !(key in Object.prototype)) {
target[key] = val
return val
}
// 处理新增对象属性
const ob = target.__ob__
if (!ob) {
target[key] = val
return val
}
// 将新属性转为响应式
defineReactive(ob.value, key, val)
ob.dep.notify()
return val
}
关键点解析
- 数组处理:通过调用数组的 splice 方法触发响应式更新,因为 Vue 重写了数组的变异方法。
- 对象处理:通过 defineReactive 方法为新属性添加 getter/setter,使其成为响应式属性。
- 依赖通知:手动触发依赖收集器(dep.notify())通知所有订阅者进行更新。
使用示例
// 对象示例
let obj = { a: 1 }
Vue.set(obj, 'b', 2) // 添加响应式属性b
// 数组示例
let arr = [1, 2, 3]
Vue.set(arr, 1, 4) // 修改索引1的值为4
注意事项
- Vue 3 中使用的是 Proxy 实现响应式,因此不再需要 Vue.set,可以直接赋值。
- 对于嵌套对象,仍然需要确保父对象是响应式的才能正确触发更新。
- 在组件中更推荐使用 this.$set 实例方法,其原理与 Vue.set 相同。






