1. 程式人生 > >關於 vue 不能 watch 陣列變化 和 物件變化的解決方案

關於 vue 不能 watch 陣列變化 和 物件變化的解決方案

vue 監聽陣列和物件的變化

vue 監聽陣列

vue 實際上可以監聽陣列變化,比如:

data () {
  return {
    watchArr: [],
  };
},
watchArr (newVal) {
  console.log('監聽:' + newVal);
},
created () {
  setTimeout(() => {
    this.watchArr = [1, 2, 3];
  }, 1000);
},

再如使用 splice(0, 2, 3) 從陣列下標 0 刪除兩個元素,並在下標 0 插入一個元素 3:

data () {
  return
{ watchArr: [1, 2, 3], }; }, watchArr (newVal) { console.log('監聽:' + newVal); }, created () { setTimeout(() => { this.watchArr.splice(0, 2, 3); }, 1000); },

push 陣列也能夠監聽到

vue 無法監聽陣列變化的情況

但是,陣列在下面兩種情況無法監聽:

  1. 利用索引直接設定一個數組項時,例如:arr[indexOfItem] = newValue;
  2. 修改陣列的長度時,例如:arr.length = newLength;

舉例無法監聽陣列變化的情況

  1. 利用索引直接修改陣列值
    data () {
      return {
        watchArr: [{
          name: 'krry',
        }],
      };
    },
    watchArr (newVal) {
      console.log('監聽:' + newVal);
    },
    created () {
      setTimeout(() => {
        this.watchArr[0].name = 'xiaoyue';
      }, 1000);
    },
  1. 修改陣列的長度長度大於原陣列就將後續元素設定為 undefined長度小於原陣列就將多餘元素截掉
    data () {
      
    return { watchArr: [{ name: 'krry', }], }; }, watchArr (newVal) { console.log('監聽:' + newVal); }, created () { setTimeout(() => { this.watchArr.length = 5; }, 1000); },

    上面的 watchArr 變成    

vue 無法監聽陣列變化的解決方案

  1. this.$set(arr, index, newVal);
    data () {
      return {
        watchArr: [{
          name: 'krry',
        }],
      };
    },
    watchArr (newVal) {
      console.log('監聽:' + newVal);
    },
    created () {
      setTimeout(() => {
        this.$set(this.watchArr, 0, {name: 'xiaoyue'});
      }, 1000);
    },
  1. 使用陣列 splice 方法可以監聽,例子上面有

  2. 使用臨時變數直接賦值的方式,原理與直接賦值陣列一樣

    data () {
      return {
        watchArr: [{
          name: 'krry',
        }],
      };
    },
    watchArr (newVal) {
      console.log('監聽:' + newVal);
    },
    created () {
      setTimeout(() => {
        let temp = [...this.watchArr];
        temp[0] = {
          name: 'xiaoyue',
        };
        this.watchArr = temp;
      }, 1000);
    },

vue 監聽物件

vue 可以監聽直接賦值的物件

this.watchObj = {name: 'popo'};

vue 不能監聽物件屬性的新增、修改、刪除

vue 監聽物件的解決方法

  1. 使用 this.$set(object, key, value)
  2. 使用深度監聽 deep: true,只能監聽原有屬性的變化,不能監聽增加的屬性
    mounted () {
      // 這裡使用深度監聽 blog 物件的屬性變化,會觸發 getCatalog 方法
      this.$watch('blog', this.getCatalog, {
        deep: true,
      });
    },
  1. 使用 this.set(obj, key, val) 來新增屬性(vue 無法監聽 this.set 修改原有屬性)
    this.$set(this.watchObj, 'age', 124);

delete this.watchObj[‘name’](vue 無法監聽 delete 關鍵字來刪除物件屬性)

  1. 使用 Object.assign 方法,直接賦值的原理監聽(最推薦的方法)
    this.watchObj = Object.assign({}, this.watchObj, {
      name: 'xiaoyue',
      age: 15,
    });

原文地址: