Flud+
18.7MB · 2026-03-23
在 Vue 2 开发中,你是否遇到过“明明数据变了,视图却没动”的诡异情况?这通常不是代码逻辑问题,而是由于 Vue 2 基于 Object.defineProperty 的响应式原理存在天然的局限性。本文将带你攻克这些响应式盲区。
Vue 2 在初始化阶段,会遍历 data 中的属性并使用 Object.defineProperty 将其转为 getter/setter。
它的核心问题在于:
如果你直接通过 this.obj.newKey = value 赋值,Vue 是无法感知的。
新增属性:使用 this.$set (或全局 Vue.set)。
this.$set(target, key, value)this.$set(this.user, 'age', 18)删除属性:使用 this.$delete (或全局 Vue.delete)。
如果你需要一次性增加多个属性,不要写一堆 $set,Vue2 可以对象引用变化,最高效的方法是替换整个对象引用:
// 这种方式 Vue 能够通过对象的引用变化来触发更新
this.user = Object.assign({}, this.user, {
age: 18,
gender: 'male'
});
// 批量更新user对象属性
this.user = {
...this.user,
age: 20,
gender: '男',
address: '北京'
}
在 Vue 2 中,直接执行 this.items[0] = 'new' 是不会触发更新的。解决方案同样是使用 this.$set,以及使用vue重写的相关数组方法。
只要调用以下方法,Vue 就会自动检测到变化并更新视图:
push() / pop():队尾操作unshift() / shift():队头操作splice():最万能,可实现增、删、改。sort():排序。reverse():翻转。根据索引修改值:
this.items[index] = newValuethis.$set(this.items, index, newValue) 或 this.items.splice(index, 1, newValue)修改数组长度:
this.items.length = 0 (清空数组失效)this.items.splice(0) 或 this.items = []Vue 3 使用了 ES6 Proxy:Proxy 代理的是整个对象而不是属性。
优势:Proxy 可以原生到属性的动态添加、删除,以及数组索引的变化,因此在 Vue 3 中,你不再需要使用 $set 了!
vue2对象新增属性:首选 this.$set,批量新增选 Object.assign。
vue2数组修改:养成使用 splice 或 push 等 7 个变异方法的习惯。
调试技巧:如果视图没更新,先用 console.log 确认数据是否变了,再检查是否触碰了上述响应式盲区。