vue 2 增删属性需 $set/$delete,vue 3 直接赋值或 delete 即可响应;数组索引赋值和 length 修改均不响应,须用变异方法或 set;嵌套对象需确保每层均为 reactive 才能深层响应。

Vue 的响应式系统能自动追踪数据变化并更新视图,但增删改操作是否“自动响应”,取决于 Vue 版本和具体写法。Vue 2 和 Vue 3 在底层机制(Object.defineProperty vs Proxy)上的差异,直接导致了行为区别。掌握这些边界,才能避免视图不更新的“幽灵 bug”。
对象新增属性:Vue 2 要手动,Vue 3 可直接
Vue 2 中,响应式对象初始化后新增属性(如 obj.newKey = 'val')不会触发更新,因为 Object.defineProperty 无法监听后续添加的键。
必须使用:
- this.$set(obj, 'newKey', 'val') 或 Vue.set(obj, 'newKey', 'val')
- 或用新对象替换:this.obj = { ...this.obj, newKey: 'val' }
Vue 3 基于 Proxy,可拦截属性访问,因此 reactive({}) 后直接 obj.newKey = 'val' 就是响应式的,无需额外调用 set。
对象删除属性:Vue 2 要手动,Vue 3 可直接
Vue 2 中,delete obj.key 不会触发更新,同样因 Object.defineProperty 无法感知删除动作。
必须使用:
- this.$delete(obj, 'key') 或 Vue.delete(obj, 'key')
- 或置为 null/undefined:this.obj.key = null(会触发更新,但保留键)
Vue 3 中,delete obj.key 是完全响应式的,Proxy 的 deleteProperty 拦截器会触发依赖更新。
数组索引赋值与长度变更:两个版本都需注意
直接通过索引设置值(arr[0] = newItem)或修改 length(arr.length = 0)在 Vue 2 和 Vue 3 中均不会触发响应式更新——这是数组的共性限制。
正确做法:
- 用变异方法:push()、pop()、shift()、unshift()、splice()、sort()、reverse()
- 用 this.$set(arr, index, value)(Vue 2)或 set(arr, index, value)(Vue 3 的 reactivity API)
- 用 arr.splice(index, 1, newValue) 替代直接赋值
新增元素推荐优先用 push/unshift/splice;若需精确控制索引位置,再考虑 set。
嵌套对象与深层响应:别掉进“半响应”陷阱
即使父对象是 reactive 的,如果某一层是普通对象(非 reactive 创建),其内部变化仍不会响应。
例如:
- const state = reactive({ user: {} }); state.user.name = 'Alice'; → name 变更不响应(user 是普通对象)
- 应改为:state.user = reactive({ name: 'Alice' }) 或 state.user = { name: 'Alice' }(Vue 3 会自动深层转为响应式)
Vue 3 对 reactive 的嵌套对象有自动递归处理,但前提是初始赋值是对象字面量或 reactive 包裹的对象;若中途赋值为 plain object,需手动 reactive 包裹。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











