Skip to content

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 在变异对象或数组时,由于引用指向相同,无法保留变异前的值副本。

小结

  1. vue2中使用索引操作数据,数据会发生改变,
  2. 使用变异方法或者$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))
    }
  },

这样就可以正确监测到数组的新旧值变化了。

总结 ​

  1. Vue2 中通过索引直接修改数组:

    • ❌ 视图不会更新
    • ❌ watch 不会触发
  2. 使用变异方法或 $set:

    • ✅ 视图会更新
    • ✅ watch 会触发
    • ❌ 但无法获取正确的新旧值对比
  3. 最佳实践:

    • 使用变异方法或 $set 来修改数组
    • 需要监测新旧值时,使用 computed 配合 watch