vue 2 中新增对象属性需用 vue.set 或 vm.$set 才能响应式,直接赋值无效;vue 3 借助 proxy 天然支持新增/删除属性,但初始化定义完整结构仍更佳。

Vue.js 在初始化时会对 data 中已存在的属性进行响应式转换,但后续直接给对象添加新属性(如 obj.newProp = value)不会触发视图更新——因为该属性未被 Object.defineProperty 劫持。要让新增属性具备响应式能力,必须显式调用 Vue 提供的专用方法。
使用 Vue.set 或 vm.$set 添加响应式属性
这是最常用、最推荐的方式,适用于 Vue 2。它会为对象新增属性并同步建立 getter/setter,确保依赖收集和视图更新正常工作。
-
语法统一:两者功能完全相同,
vm.$set是实例方法,Vue.set是全局方法 -
参数顺序固定:目标对象、属性名(字符串)、属性值,例如:
this.$set(this.user, 'phone', '138xxxx') -
仅支持嵌套对象或数组:第一个参数不能是 Vue 实例本身或
vm.$data,只能是其内部某个已有响应式对象(如this.user、this.list[0])
避免直接赋值导致响应失效
以下写法看似简洁,但无法触发更新:
-
this.user.address = { city: 'Beijing' }→address非响应式 -
this.items['newKey'] = 'value'→ 索引访问方式同样绕过响应式系统 -
Object.assign(this.user, { avatar: '/img.jpg' })→ 新增字段不被监听
若需批量添加,应创建新对象替代原对象:this.user = Object.assign({}, this.user, { avatar: '/img.jpg', bio: '...' })。
Vue 3 中的差异与替代方案
Vue 3 使用 Proxy 重写了响应式系统,对对象新增/删除属性天然支持——只要操作的是 reactive() 或 ref() 包裹的对象,无需额外 API。
- 例如:
const state = reactive({ name: 'Alice' }); state.age = 25;→age自动响应 - 但仍建议在初始化时尽量定义完整结构,保持代码可预测性
- 兼容写法:若需在 Vue 2/3 共存项目中统一逻辑,仍可保留
Vue.set调用(Vue 3 中该方法已被标记为兼容层,内部转为reactive操作)
补充:数组索引赋值的特殊处理
直接通过下标设置数组项(如 arr[1] = newItem)也不会触发更新,原因同对象新增属性。
- 正确做法:使用
this.$set(arr, index, newItem) - 或改用内置响应式方法:
arr.splice(index, 1, newItem) - 避免使用
filter、map等返回新数组的方法直接赋值,它们不修改原数组引用
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











