Vue踩坑之旅(一)—— 数组、对象的监听

作为一个接触 vue 才一个多月的小白,马上就接手基于 vue 的大型商城项目,其间真是跌跌撞撞踩了好多坑(o(╥﹏╥)o)。在此写下自己的踩坑之旅,希望给跟我一样还在自学 vue 的同学一些帮助,另外大佬如果有更好的解决办法,请不吝赐教。

watch 侦听属性有如下属性:
1. handler:监听数组或对象的属性时用到的方法
2. deep:深度监听,为了发现对象内部值的变化,可以在选项参数中指定 deep:true 。
3. immediate: 在选项参数中指定 immediate: true 将立即以表达式的当前值触发回调
4. tips: 只要bet中的属性发生变化(可被监测到的),便会执行handler函数;如果想监测具体的属性变化,如pokerHistory变化时,才执行handler函数,则可以利用计算属性computed做中间层。

watch 侦听属性其实用得挺多的,但是我之前只是简单的应用了:

data() {
 return { 
  frontPoints: 0 
 }
},
watch: {
 frontPoints(newValue, oldValue) {
   console.log(newValue)
 }
}复制代码

但是现在项目中需要侦听的属性结构比较复杂:

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 也会报同样的错误。


其实数组和对象的 newValue 和 oldValue 是相等的,都指向同一个引用对象,所以watch 无法监听到变化

之后我就总结了几种情况:

1. watch 普通属性(非数组和对象)

2. watch 数组(不能使用 deep: true )

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 对象

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'
    }
  },复制代码


转载于:https://juejin.im/post/5d02009ae51d4510bf1d6665

猜你喜欢

转载自blog.csdn.net/weixin_33670786/article/details/93176284