Vue2 中数组操作的注意事项
在 Vue2 中,虽然 data 中的数据是响应式的,底层也重写了数组的七个变异方法,但在操作数组时仍然存在一些需要注意的问题。
1. 通过索引直接修改数组
html
<template>
<div>
<div @click='bth'> but</div>
</div>
</template>
<script>
export default {
data() {
return {
subjectList: [{ name: 'jack' }, 555, 'abc', ['dd']],
}
},
watch: {
subjectList: {
handler(n, o) {
console.log(n, o)
},
deep:true
},
},
methods: {
bth() {
console.log('点击了')
this.subjectList[0] = '111'
console.log(this.subjectList)
},
},
}
</script>结果: 通过索引直接修改数组元素时,虽然数据确实被修改了,但存在以下问题:
- 视图不会更新
- watch 监听器不会被触发

2. 使用变异方法或 $set 修改数组
js
watch: {
subjectList: {
handler(n, o) {
console.log('newValue:',n)
console.log('oldvalue:', o)
},
},
},
methods: {
bth() {
console.log('点击了')
// this.subjectList[3] ='ccc'
// this.subjectList.pop()
this.$set(this.subjectList,3,'fff')
console.log(this.subjectList)
},
},结果: 使用数组变异方法(push、pop、shift、unshift、splice、sort、reverse)或 $set 时:
- 视图会正常更新
- watch 监听器会被触发
- 但无法获取到正确的新旧值对比,因为它们指向同一引用

注意:Vue2 在变异对象或数组时,由于引用指向相同,无法保留变异前的值副本。
小结
- vue2中使用索引操作数据,数据会发生改变,
- 使用变异方法或者$set操作数组,数组会发生变化,
引用官方文档的说法:注意:在变异(不是替换)对象或数组时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue不会保留变异之前值的副本。
3. 如何正确监测数组的变化?
可以结合 watch 和 computed 来实现:
js
data() {
return {
subjectList: [{ name: 'jack' }, 555, 'abc', ['dd']],
}
},
watch: {
subjectListData: {
handler(n, o) {
console.log('newValue:',n)
console.log('oldvalue:', o)
},
deep:true
},
},
computed:{
subjectListData(){
console.log('computed执行了')
return[...this.subjectList]
// return JSON.parse(JSON.stringify(xxx))
}
},这样就可以正确监测到数组的新旧值变化了。
总结
Vue2 中通过索引直接修改数组:
- ❌ 视图不会更新
- ❌ watch 不会触发
使用变异方法或 $set:
- ✅ 视图会更新
- ✅ watch 会触发
- ❌ 但无法获取正确的新旧值对比
最佳实践:
- 使用变异方法或 $set 来修改数组
- 需要监测新旧值时,使用 computed 配合 watch