Vue 不能 watch 数组变化 和 对象变化的解决方案

12,502 阅读2分钟
vue监听数组和对象的变化

监听数组

1 直接赋值

data() {
    return {
      watchArr: []
    };
  },
  watch: {
    watchArr(newVal) {
      console.log("监听:" + newVal);
    }
  },
  created() {
    this.watchArr = [1, 2, 3];
  },

2 再如使用 splice(0, 2, 3) 从数组下标 0 删除两个元素,并在下标 0 插入一个元素 3

  data() {
    return {
      watchArr: [1, 2, 3],
    };
  },
  watch: {
    watchArr(newVal) {
      console.log("监听:" + newVal);
    }
  },
  created() {
    this.watchArr.splice(0, 2, 3);
  },

3 push 数组也能够监听到


  • 无法监听数组变化的情况

    但是,数组在下面两种情况无法监听:

    利用索引直接设置一个数组项时,例如:arr[indexOfItem] = newValue; 修改数组的长度时,例如:arr.length = newLength; 举例无法监听数组变化的情况

    1 利用索引直接修改数组值

      data() {
        return {
          watchArr: [
            {
              name: "krry"
            }
          ]
        };
      },
      watch: {
        watchArr(newVal) {
          console.log("监听:" + newVal);
        }
      },
      created() {
        this.watchArr[0].name = "xiaoyue";
      },
    

    2 修改数组的长度

    长度大于原数组就将后续元素设置为 undefined,
    长度小于原数组就将多余元素截掉
    
        data() {
        return {
          watchArr: [
            {
              name: "krry"
            }
          ]
        };
      },
      watch: {
        watchArr(newVal) {
          console.log("监听:" + newVal);
        }
      },
      created() {
        this.watchArr.length = 5;
      },
    
  • 无法监听数组变化的解决方案

1  this.$set(arr, index, newVal);
2 使用数组 splice 方法可以监听,例子上面有
3 使用临时变量直接赋值的方式,原理与直接赋值数组一样
      data() {
        return {
          watchArr: [
            {
              name: "krry"
            }
          ]
        };
      },
      watch: {
        watchArr(newVal) {
          console.log("监听:" + newVal);
        }
      },
      created() {
        let temp = [...this.watchArr];
        temp[0] = {
          name: 'xiaoyue',
        };
        this.watchArr = temp;
      },

监听对象

但是 Vue 不能监听对象属性的添加、修改、删除


  • 监听对象的解决方法

    1 使用 this.set(obj, key, val) 来新增属性(Vue 无法监听 this.set 修改原有属性) 2 使用深度监听 deep: true,只能监听原有属性的变化,不能监听增加的属性

     watch: {
       obj: {
        // 这里深度监听变化,直接触发下面方法
           handler(curVal, oldVal) {
         // TODO
           },
           deep: true,
           immediate: true // 是否第一次触发
       }
   }
  3 使用 Object.assign 方法,直接赋值的原理监听(最推荐的方法)
     this.watchObj = Object.assign({}, this.watchObj, {
        name: 'xiaoyue',
        age: 15,
     });
4 直接 watch obj.key 监听某个值的变化
    watch: {
      'obj.name'(curVal, oldVal) {
        // TODO
      }
    }

原文地址:关于 vue 不能 watch 数组变化 和 对象变化的解决方案