Vue修改数组/对象 记录坑

Vue中数组与对象响应式更新技巧
本文介绍Vue中数组及对象响应式更新的方法,包括如何解决直接修改数组元素或长度导致的状态更新失败问题,以及如何正确地为已存在的对象动态添加新的响应式属性。

Vue修改数组里的数据,由于js的限制,vue检测不到以下数据的变化

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如:vm.items.length = newLength

这是常见的问题,有时候使用this.$nexttick也并不会更新数据,

为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue 相同的效果,同时也将触发状态更新:

// Vue.set
Vue.set(example1.items, indexOfItem, newValue)
// Array.prototype.splice
example1.items.splice(indexOfItem, 1, newValue)

为了解决第二类问题,你可以使用 splice

example1.items.splice(newLength)
扩展:

还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除

对于已经创建的实例,Vue 不能动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套对象添加响应式属性

var vm = new Vue({
  data: {
    userProfile: {
      name: 'Anika'
    }
  }
})

你可以添加一个新的 age 属性到嵌套的 userProfile 对象:

Vue.set(vm.userProfile, 'age', 27)

有时你可能需要为已有对象赋予多个新属性,比如使用 Object.assign() 或 _.extend()。在这种情况下,你应该用两个对象的属性创建一个新的对象。所以,如果你想添加新的响应式属性,不要像这样:

Object.assign(this.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

你应该这样做:

this.userProfile = Object.assign({}, this.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})





### Vue.js 中监听数组变化 #### Vue 2 监听数组特定项的变化 在 Vue 2 中,JavaScript 对对象数组变更的侦测存在一定的局限性。为了能够有效地监听数组中的某个具体位置的数据变动,可以采用 `this.$set` 方法来修改数组元素,从而触发视图更新[^1]。 ```javascript new Vue({ el: '#app', data: { items: ['apple', 'banana'] }, methods: { updateFirstItem(newVal) { this.$set(this.items, 0, newVal); } }, watch: { items: { handler(newValue, oldValue) { console.log('items changed from ', oldValue, ' to ', newValue); }, deep: true // 深度监视整个数组结构内的更改 } } }); ``` 上述代码展示了如何通过 `$set` 函数设置第一个项目的并确保该操作能被观察者捕捉到。同时开启了深度监听模式以便追踪内部属性的变化[^4]。 #### Vue 3 使用 Watcher 监控数组变化 对于 Vue 3 而言,在组合 API 下提供了更灵活的方式来进行状态管理以及事件监听。下面的例子说明了怎样利用 Composition API 实现同样的功能——监听数组及其成员的变化[^3]: ```javascript import { ref, watch } from "vue"; export default { setup() { const items = ref(['orange', 'grape']); function addItem(item) { items.value.push(item); } watch(items, (newValue, oldValue) => { console.log(`Array has been updated`, newValue, oldValue); }, {deep:true}); return { items, addItem }; } }; ``` 这里使用了 `ref()` 创建了一个可响应式的数组实例,并借助于 `watch()` 宏观上监测其任何改动;同样地启用了深层数组跟踪选项 `{deep:true}` 来获取详细的变更记录[^2]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值