vue 两个数据互相 watch 为什么不会无限循环
lovelmh13 opened this issue · 0 comments
lovelmh13 commented
有如下代码:
// app.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" width="25%" />
<HelloWorld :msg.sync="msg" :lastPage="thispage" />
<input type="text" v-model="thispage" />
<input type="text" v-model="msg" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: "App",
data() {
return {
msg: "msg",
thispage: "1122",
};
},
components: {
HelloWorld,
},
};
</script>
// helloword.vue
<template>
<div class="hello">
<input type="text" v-model="msgCopy" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: {
type: String,
default: "",
},
lastPage: String,
},
watch: {
lastPage(newVal, oldVal) {
console.log("watch:lastPage", newVal, oldVal);
},
msg: {
handler(newVal, oldVal) {
debugger;
console.log("watch:msg", newVal, oldVal);
this.msgCopy = newVal;
},
},
msgCopy: {
handler(newVal, oldVal) {
console.log("watch:msgCopy", newVal, oldVal);
this.$emit("update:msg", newVal);
},
},
},
mounted() {
this.msgCopy = this.msg;
},
data() {
return {
msgCopy: "",
};
},
};
</script>
打印效果如下:msg 和 msgCopy 互相修改,并且都对自身进行了 watch,但是修改了 msgCopy, 并不会一直陷入 watch 的无限循环中。
watch:msgCopy hello world1 hello world
// 中间是父组件更新 msg 的动作
watch:msg hello world1 hello world
原因
msg 是 基本类型,如果改成 复杂类型,则会死循环:
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png" width="25%" />
<HelloWorld :msg.sync="msg" :lastPage="thispage" />
<input type="text" v-model="thispage" />
<input type="text" v-model="msg.text" />
</div>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
export default {
name: "App",
data() {
return {
msg: {
text: "msg",
},
thispage: "1122",
};
},
components: {
HelloWorld,
},
};
</script>
<template>
<div class="hello">
<input type="text" v-model="msgCopy" />
</div>
</template>
<script>
export default {
name: "HelloWorld",
props: {
msg: {
type: Object,
default() {
return {};
},
},
lastPage: String,
},
watch: {
lastPage(newVal, oldVal) {
console.log("watch:lastPage", newVal, oldVal);
},
msg: {
handler(newVal, oldVal) {
debugger;
console.log("watch:msg", newVal, oldVal);
this.msgCopy = newVal;
},
},
msgCopy: {
handler(newVal, oldVal) {
console.log("watch:msgCopy", newVal, oldVal);
this.$emit("update:msg", { text: newVal });
},
},
},
mounted() {
this.msgCopy = this.msg;
},
data() {
return {
msgCopy: {
text: "copy",
},
};
},
};
</script>