Vue2:数组/对象操作避坑大全

前言

在 Vue 2 开发中,你是否遇到过"明明数据变了,视图却没动"的诡异情况?这通常不是代码逻辑问题,而是由于 Vue 2 基于 Object.defineProperty 的响应式原理存在天然的局限性。本文将带你攻克这些响应式盲区。

一、 响应式的"硬伤":为什么会失效?

Vue 2 在初始化阶段,会遍历 data 中的属性并使用 Object.defineProperty 将其转为 getter/setter。

它的核心问题在于:

  1. 无法检测对象属性的添加或删除(因为它只在初始化时进行监听)。
  2. 无法检测数组索引的直接修改和长度变化。

二、 对象操作:打破"属性新增"的僵局

1. 新增/删除属性

如果你直接通过 this.obj.newKey = value 赋值,Vue 是无法感知的。

  • 新增属性 :使用 this.$set (或全局 Vue.set)。

    • 语法:this.$set(target, key, value)
    • 示例:this.$set(this.user, 'age', 18)
  • 删除属性 :使用 this.$delete (或全局 Vue.delete)。

2. 批量修改属性

如果你需要一次性增加多个属性,不要写一堆 $set,Vue2 可以监听对象引用变化 ,最高效的方法是替换整个对象引用:

JavaScript 复制代码
// 这种方式 Vue 能够通过监听对象的引用变化来触发更新
this.user = Object.assign({}, this.user, {
  age: 18,
  gender: 'male'
});

// 批量更新user对象属性
this.user = {
  ...this.user,
  age: 20,
  gender: '男',
  address: '北京'
}

三、 数组操作:被"重写"的 7 个方法

在 Vue 2 中,直接执行 this.items[0] = 'new' 是不会触发更新的。解决方案同样是使用 this.$set,以及使用vue重写的相关数组方法。

1. 自动触发更新的方法

只要调用以下方法,Vue 就会自动检测到变化并更新视图:

  • push() / pop():队尾操作
  • unshift() / shift():队头操作
  • splice():最万能,可实现增、删、改。
  • sort():排序。
  • reverse():翻转。

2. 数组的特殊场景

  • 根据索引修改值:

    • ❌ 错误:this.items[index] = newValue
    • ✅ 正确:this.$set(this.items, index, newValue) 或 this.items.splice(index, 1, newValue)
  • 修改数组长度:

    • ❌ 错误:this.items.length = 0 (清空数组失效)
    • ✅ 正确:this.items.splice(0) 或 this.items = []

四、 进阶补充:Vue 3 是如何解决的?

  • Vue 3 使用了 ES6 Proxy :Proxy 代理的是整个对象而不是属性。

  • 优势 :Proxy 可以原生监听到属性的动态添加、删除,以及数组索引的变化,因此在 Vue 3 中,你不再需要使用 $set 了!


五、 总结

  1. vue2对象新增属性 :首选 this.$set,批量新增选 Object.assign。

  2. vue2数组修改 :养成使用 splice 或 push 等 7 个变异方法的习惯。

  3. 调试技巧 :如果视图没更新,先用 console.log 确认数据是否变了,再检查是否触碰了上述响应式盲区。

相关推荐
对空六课5 小时前
指标口径生效时间的版本查询实现
大数据·服务器·前端·算法·数据分析
对空六课5 小时前
RFM分层边界变化的回溯计算
大数据·服务器·前端·数据库·人工智能·算法·数据分析
IT_陈寒5 小时前
Vite打包的诡异行为,让我差点提交了个错误版本
前端·人工智能·后端
鹏多多5 小时前
前端是如何死去的?| 完整时间线
前端·javascript·程序员
coding漫漫长路5 小时前
海报挪进Worker画,canvas字体又变回默认了
前端
看浪的路人5 小时前
第2讲:ReAct 模式从零实现——不用框架,手写一个 Agent 内核
前端·react.js·前端框架
独孤九剑打醒他6 小时前
【原创开源·航空终极篇】氢能航空动力升级:双燃料掺氢、富氧补气与露天储氢安全模型
前端·架构·开源·硬件工程·能源
律宏阔6 小时前
阿里云 ESA + Pages 域名部分电脑无法访问
前端
毕业设计7036 小时前
(免费领源码)基于node的学生公寓管理系统06412- java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·mysql·node.js·maven·mybatis·express·b/s
Lank_M6 小时前
canvas 第一次画字没用上字体,字体却是它要来的
前端