lovelmh13 / myBlog

个人博客 记录菜狗的学习之路
6 stars 0 forks source link

vue 两个数据互相 watch 为什么不会无限循环 #152

Open lovelmh13 opened 3 years ago

lovelmh13 commented 3 years ago

有如下代码:

// 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>