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)
- 利用Array.splice方法来操作数组
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') },
-