Vue踩坑之旅(一)—— 數組、對象的監聽

做爲一個接觸 vue 才一個多月的小白,立刻就接手基於 vue 的大型商城項目,其間真是跌跌撞撞踩了好多坑(o(╥﹏╥)o)。在此寫下本身的踩坑之旅,但願給跟我同樣還在自學 vue 的同窗一些幫助,另外大佬若是有更好的解決辦法,請不吝賜教。javascript

watch 偵聽屬性有以下屬性:
1. handler:監聽數組或對象的屬性時用到的方法
2. deep:深度監聽,爲了發現對象內部值的變化,能夠在選項參數中指定 deep:true 。
3. immediate: 在選項參數中指定 immediate: true 將當即以表達式的當前值觸發回調
4. tips: 只要bet中的屬性發生變化(可被監測到的),便會執行handler函數;若是想監測具體的屬性變化,如pokerHistory變化時,才執行handler函數,則能夠利用計算屬性computed作中間層。

watch 偵聽屬性其實用得挺多的,可是我以前只是簡單的應用了:vue

data() {
 return { 
  frontPoints: 0 
 }
},
watch: {
 frontPoints(newValue, oldValue) {
   console.log(newValue)
 }
}複製代碼

可是如今項目中須要偵聽的屬性結構比較複雜:java

data() {  
  return {    
    commentForm: {      
      OrderId: null,      
      ShopScore: null,
      ScoreDetailList: [
        // {
        // CommodityScore: null,
        // OrderDetailId: null,
        // Content: '',
        // FileIdLIst: []
        // },
      ]
    }
  }
}複製代碼

若是我想監聽 ShopScore 和 未知長度的數組  ScoreDetailList數組

watch: {
  'commentForm.ScoreDetailList': {
    function(val) {
      console.log(val)
    },
    deep: true
  },
  'commentForm.ShopScore': function (val) {
    console.log(val)
  }
}複製代碼

此時就會報錯:函數


使用深度監聽 deep: true 也會報一樣的錯誤。ui


其實數組和對象的 newValue 和 oldValue 是相等的,都指向同一個引用對象,因此watch 沒法監聽到變化

以後我就總結了幾種狀況:this

1. watch 普通屬性(非數組和對象)spa

2. watch 數組(不能使用 deep: true )code

data() {
 return {
   Array1: new Array(11).fill(0)
 }
},
watch: {
  Array1: { handler(newValue, oldValue) {
    newValue.forEach((item, i) => {
      if (item !== oldValue[i]) {
        console.log(newValue) 
      }
    }
   }, 
  }
}複製代碼

3. watch 對象orm

data() {
 return {
  obj: {
   age: 53,
   name: 'lakey'
  }
  }
},
watch: {
 obj: {
  handler(newValue, oldValue) {
    console.log(newValue)    
    },
  deep: true
 }
}複製代碼

4. watch 對象具體屬性

這裏有兩個方案,已經是直接寫具體屬性:

data() {
 return {
  obj: {
   age: 53,
   name: 'lakey'
  }
  }
},
watch: {
 'obj.name': {
  handler(newValue, oldValue) {
   console.log(newValue)    
    }
 }
}複製代碼

另外一種,是活用計算屬性 computed

data() {
 return {
  obj: {
   age: 53,
   name: 'lakey'
  }
  }
},
computed: {
  obj() {
    return this.obj.name
  }
},
watch: {
  name(newValue, oldValue) {
    console.log(newValue)
  }
}
複製代碼

------------------------------補上個人項目的解決辦法----------------------------------------


watch: {
    'commentForm.ScoreDetailList': {
      handler(newVal) {
        // 假設沒有變化
        let flag = false
        newVal.forEach((item) => {
          if (item.CommodityScore) {
            flag = true
          }
          if (this.Trim(item.Content)) {
            flag = true
          }
        })
        if (flag) {
          this.errmessage = ''
          this.$refs.tabBox.style.borderColor = '#d9e3eb'
        }
      },
      deep: true
    },
    'commentForm.ShopScore': function () {
      this.errmessage = ''
      this.$refs.tabBox.style.borderColor = '#d9e3eb'
    }
  },複製代碼
相關文章
相關標籤/搜索