vue.set实现原理
Vue.set 的实现原理
Vue.set 是 Vue.js 提供的一个全局 API,用于向响应式对象添加新属性并确保新属性也是响应式的。其核心原理基于 Vue 的响应式系统。
响应式系统的核心机制
Vue 的响应式系统通过 Object.defineProperty 或 Proxy(Vue 3)实现数据劫持。当对象被初始化为响应式时,Vue 会递归地遍历对象的所有属性,将它们转换为 getter/setter。但对于后续动态添加的属性,Vue 无法自动检测到变化。
Vue.set 的作用
Vue.set 解决了动态添加属性的响应式问题。它通过以下方式工作:
- 对于目标对象是数组的情况,使用数组的 splice 方法触发响应式更新。
- 对于目标对象是普通对象的情况,通过 defineReactive 方法将新属性转换为响应式属性。
- 触发依赖通知,通知所有订阅者(Watcher)进行更新。
源码解析
以下是 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
}
// 处理新增属性
const ob = target.__ob__
if (!ob) {
target[key] = value
return value
}
// 将新属性转为响应式
defineReactive(ob.value, key, value)
// 通知依赖更新
ob.dep.notify()
return value
}
使用场景
Vue.set 主要在以下场景中使用:
- 动态添加对象属性时
- 通过索引修改数组元素时(替代直接索引赋值)
- 添加数组新元素时(超出当前数组长度)
与直接赋值的区别
直接给对象添加新属性不会触发视图更新,因为新属性没有被转换为响应式属性。Vue.set 能够确保新属性被正确劫持并触发视图更新。
Vue 3 的变化
在 Vue 3 中,由于使用 Proxy 实现响应式,Vue.set 不再是必须的,因为 Proxy 可以拦截所有属性访问和修改操作,包括动态添加的属性。但为了兼容性,Vue 3 仍然保留了类似功能的 API。







