vue视图不更新以及数据watch不到问题总结

1、源代码

<template>
  <div>
    <div>
      <button @click="handleTestArr">testArr</button>
      <button @click="handleTestObj">testhandleTestObj</button>
      <p>testArr</p>
      <ul>
        <li v-for="arr in testArr" :key="arr">{{ arr }}</li>
      </ul>
      <a-divider></a-divider>
      <p>testObj</p>
      <p>a: {{ testObj.a }}</p>
      <p>b: {{ testObj.b }}</p>
      <a-divider></a-divider>
    </div>
  </div>
</template>
<script>
const obj = {
  a: 2,
  b: 4,
  c: 6,
}
const arr = ['a', 'b', 'c', 'd']
export default {
  data() {
    return {
      testArr: [1, 2, 3, 4, 5],
      testObj: {
        a: 1,
        b: 2,
      },
    }
  },
  methods: {
    handleTestArr() {
      this.testArr = arr
    },
    handleTestObj() {
      this.testObj = obj
    },
  },
  watch: {
    testArr() {
      console.log('arr')
    },
    testObj() {
      console.log('obj')
    },
  },
}
</script>

2、关于视图

2.1、操作数组

    handleTestArr() {
      // this.testArr = arr//更新
      // this.testArr = [1, 2]//更新
      // this.testArr.push(6) /更新
      // this.testArr = this.testArr.slice(0, 2) //更新
       this.testArr[0] = 9 //视图不更新,this.testArr已改变
    },
  • 总结:重新指定一个数组,视图会更新,但是直接改变单个元素视图不会更新
  • 解决方法:
    • 利用Array.splice方法来操作数组 this.testArr.splice(0, 1, 9)
    • 利用vue提供的接口$set来触发试图更新 this.$set(this.testArr,0,9)

2.2、操作对象

 handleTestObj() {
      // this.testObj = obj //更新
      // this.testObj = { a: 2, b: 3 } //更新
      // this.testObj['a'] = 2 //更新
      // this.testObj.a = 2 //更新
    },
  • 总结:操作对象的属性,目前测试的几种情况下,视图都会变化

  • 某些未知情况下可能不更新视图,同样可以用$set来手动更新 this.$set("对象","对象属性","值")

3、关于watch

3.1、操作数组

  handleTestArr() {
      // this.testArr = arr //触发watch
      // this.testArr = [1, 2] //触发watch
      // this.testArr.push(6) //触发watch
      // this.testArr = this.testArr.slice(0, 2) //触发watch
      // this.testArr[0] = 9 //不触发watch
      this.$set(this.testArr, 0, 9)//触发watch
    },
  • 总结:直接改变某个元素,不触发watch(设置了deep:true也无效),可用过$set来处理

3.2、操作对象

    handleTestObj() {
      // this.testObj = obj //触发watch
      // this.testObj = { a: 2, b: 3 } //触发watch
      // this.testObj['a'] = 2 //不触发watch
      // this.testObj.a = 2 //不触发watch
    },
  • 总结:重新给对象赋值时能够触发watch,改变某个属性时不能触发

  • 解决方法:

    • 利用deep:true属性深度监听

    • 监听具体的某个属性:

       'testObj.a'(newVal, oldVal) {
            console.log('obj')
       },
      
posted @ 2021-03-09 14:48  baifangzi  阅读(1542)  评论(0编辑  收藏  举报