由于vue3.x发布后,watch属性的行为模式有所变化。在日常使用中会经常搞混或搞不清楚watch是否会监听到事件的变化。这里记录VUE2.x中watch监听数组/对象的行为模式。作为日后迷糊时的提醒。
总结
普通数组
- 数组push时,可以监听到数组变化,页面内容即时刷新。
- 通过splice删除数组元素时,可以监听到数组变化,页面内容即时刷新。
- 直接修改数组元素的值时,不能监听到数组变化,页面内容不会刷新。
- 通过set函数修改追加新的元素时,会触发监听事件并且页面即时刷新。
对象数组
- 数组push时,可以监听到数组变化,页面内容即时刷新。
- 通过splice删除数组元素时,可以监听到数组变化,页面内容即时刷新。
- 直接修改数组元素中的属性值时,不能监听到数组变化,页面内容即时刷新。
普通对象
属性的增加删除更新都不会触发watch事件。也不会触发画面刷新。
数组组件间传递
- 普通数组,触发行为与当前组件中相同。
- 对象数组,触发行为与当前组件中相同。
代码
//WatchArray.vue
<template>
<div class="hello">
<section>
<h2>监听数字数组</h2>
<button @click="addNumberArr">增加数字元素</button>
<button @click="deleteNumberArr">删除元素</button>
<button @click="updateNumberArr">通过下标直接更新元素</button>
<button @click="updateNumberArrBySet">通过SET更新元素</button>
<button @click="addNumberArrBySet">通过SET新增元素</button>
<ul>
<li
v-for="item in arr"
:key="item"
>{{item}}</li>
</ul>
</section>
<section>
<div>
<h2>监听对象数组</h2>
<button @click="addObjectArr">增加对象元素</button>
<button @click="deleteObjectArr">删除对象元素</button>
<button @click="updateObjectArr">更新元素</button>
<ul>
<li
v-for="item in objArr"
:key="item.id"
>{{item.lable}}</li>
</ul>
</div>
</section>
<section>
<h2>监听对象属性变化测试</h2>
<button @click="addObjectAttribute">增加属性</button>
<button @click="deleteObjectAttribute">删除属性</button>
<button @click="updateObjectAttribute">更新属性</button>
<br>
<span>{{ obj }}</span>
<br>
<br>
</section>
<section>
<div>
<button @click="addChildNumberArr">增加子级数字元素</button>
<button @click="deleteChildNumberArr">删除子级元素</button>
<button @click="updateChildNumberArr">更新子级元素</button>
</div>
<div>
<button @click="addChildObjectArr">增加子级对象元素</button>
<button @click="deleteChildObjectArr">删除子级对象元素</button>
<button @click="updateChildObjectArr">更新子级元素</button>
</div>
<WachCHild
:arr="childArr"
:objArr="childObjArr"
/>
</section>
</div>
</template>
<script>
import WachCHild from "./WatchChild.vue";
export default {
name: "WatchArray",
components: {
WachCHild,
},
data: function () {
return {
arr: [1, 2, 3, 4, 5],
objArr: [{ id: "0", lable: "obj0" }],
obj: {
key0: "key0",
},
childArr: [0, 1, 2, 3],
childObjArr: [{ id: "0", lable: "obj0" }],
};
},
watch: {
arr() {
alert("监听数组push");
},
objArr() {
alert("监听对象数组push");
},
obj() {
alert("检测到属性发生变化");
},
childArr() {
alert("监听传递给子级数组的push");
},
childObjArr() {
alert("监听传递给子级对象数组push");
},
},
methods: {
addNumberArr() {
this.arr.push(this.arr.length);
},
deleteNumberArr() {
this.arr.splice(this.arr.length - 1, 1);
},
updateNumberArr() {
this.arr[this.arr.length - 1] = "update";
},
updateNumberArrBySet() {
// let len = this.arr.length - 1;
this.$set(this.arr, this.arr.length - 1, "$set");
},
addNumberArrBySet() {
this.$set(this.arr, this.arr.length, "$set-add");
},
addObjectArr() {
this.objArr.push({
id: this.objArr.length,
lable: `obj${this.objArr.length}`,
});
},
deleteObjectArr() {
this.objArr.splice(this.objArr.length - 1, 1);
},
updateObjectArr() {
this.objArr[this.objArr.length - 1].lable = "test";
},
addObjectAttribute() {
this.obj.key1 = "key1";
},
deleteObjectAttribute() {
delete this.obj.key1;
},
updateObjectAttribute() {
this.obj.key1 = "demo";
},
addChildNumberArr() {
this.childArr.push(this.childArr.length);
},
deleteChildNumberArr() {
this.childArr.splice(this.childArr.length - 1, 1);
},
updateChildNumberArr() {
this.childArr[this.childArr.length - 1] = "update";
},
addChildObjectArr() {
this.childObjArr.push({
id: this.childObjArr.length,
lable: `obj${this.childObjArr.length}`,
});
},
deleteChildObjectArr() {
this.childObjArr.splice(this.childObjArr.length - 1, 1);
},
updateChildObjectArr() {
this.childObjArr[this.childObjArr.length - 1].lable = "test";
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>
//WatchChild.vue
<template>
<div>
<h2>监听父级传递过来的数字数组</h2>
<ul>
<li
v-for="item in arr"
:key="item"
>{{item}}</li>
</ul>
<h2>监听父级传递过来的对象数组</h2>
<ul>
<li
v-for="item in objArr"
:key="item.id"
>{{item.lable}}</li>
</ul>
</div>
</template>
<script>
export default {
name: "watch-child",
props: {
arr: Array,
objArr: Array,
},
watch: {
arr() {
alert("子级中监听父级普通数组的操作");
},
objArr() {
alert("子级中监听父级对象数组的操作");
},
},
};
</script>