1.开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中;
2.当数据变化时,template会自动进行更新来显示最新的数据;
3.但是在某些情况下,我们希望在代码逻辑中监听某个数据的变化,比如某个数据变化的时候,我们要执行一些别的东西,不旦旦是更新template中绑定的东西。这个时候就需要用侦听器watch来完成了;
computed:当依赖的数据发生改变的时候,就会重新计算,更新反应到页面上面。没有动作。
watch:当我们相对某个属性进行监听,某个属性发生改变的时候,不想单单的让他更新熏染到template的mastach语法里面,比如我们想数据发生变化,我们需要发送网络请求,axios.get("...)的时候,我们就需要使用watch。
watch可以是一个函数,也可以是一个对象,对象的化,第一个是函数,第二个是deep:是不是深度监听。
第三个是immediate,一般默认的是false,如果这样的化,第一次是不会执行这个监听函数的,第一次的oldvalue是undifend,就是页面渲染出来,数据的默认值挂载到页面这一次是不会执行的。第二个数据改变才会执行。
设置为true的化,就是第一次也会执行这个函数。并且newvalue是默认值,oldvalue是undifined。
- 侦听器的基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
您的问题: <input type="text" v-model="question">
<!-- <button @click="queryAnswer">查找答案</button> -->
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
// 侦听question的变化时, 去进行一些逻辑的处理(JavaScript, 网络请求)
question: "Hello World",
anwser: ""
}
},
watch: {
// question侦听的data中的属性的名称
// newValue变化后的新值
// oldValue变化前的旧值
question: function(newValue, oldValue) {
console.log("新值: ", newValue, "旧值", oldValue);
this.queryAnswer();
}
},
methods: {
queryAnswer() {
console.log(`你的问题${this.question}的答案是哈哈哈哈哈`);
this.anwser = "";
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
- 侦听器的配置选项
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{info.name}}</h2>
<button @click="changeInfo">改变info</button>
<button @click="changeInfoName">改变info.name</button>
<button @click="changeInfoNbaName">改变info.nba.name</button>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
info: { name: "why", age: 18, nba: {name: 'kobe'} }
}
},
watch: {
// 默认情况下我们的侦听器只会针对监听的数据本身的改变(内部发生的改变是不能侦听)
// info(newInfo, oldInfo) {
// console.log("newValue:", newInfo, "oldValue:", oldInfo);
// }
// 深度侦听/立即执行(一定会执行一次)
info: {
handler: function(newInfo, oldInfo) {
console.log("newValue:", newInfo.nba.name, "oldValue:", oldInfo.nba.name);
},
deep: true, // 深度侦听
// immediate: true // 立即执行
}
},
methods: {
changeInfo() {
this.info = {name: "kobe"};
},
changeInfoName() {
this.info.name = "kobe";
},
changeInfoNbaName() {
this.info.nba.name = "james";
}
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
3.侦听器的其他配置方式
image.png
image.png
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="app"></div>
<template id="my-app">
<h2>{{info.name}}</h2>
<button @click="changeInfo">改变info</button>
<button @click="changeInfoName">改变info.name</button>
<button @click="changeInfoNbaName">改变info.nba.name</button>
<button @click="changeFriendName">改变friends[0].name</button>
</template>
<script src="../js/vue.js"></script>
<script>
const App = {
template: '#my-app',
data() {
return {
info: { name: "why", age: 18, nba: {name: 'kobe'} },
friends: [
{name: "why"},
{name: "kobe"}
]
}
},
watch: {
info(newValue, oldValue) {
console.log(newValue, oldValue);
},
"info.name": function(newName, oldName) {
console.log(newName, oldName);
},
"friends[0].name": function(newName, oldName) {
console.log(newName, oldName);
},
// friends: {
// handler(newFriends, oldFriend) {
// },
// deep: true
// }
},
methods: {
changeInfo() {
this.info = {name: "kobe"};
},
changeInfoName() {
this.info.name = "kobe";
},
changeInfoNbaName() {
this.info.nba.name = "james";
},
changeFriendName() {
this.friends[0].name = "curry";
}
},
created() {
const unwatch = this.$watch("info", function(newInfo, oldInfo) {
console.log(newInfo, oldInfo);
}, {
deep: true,
immediate: true
})
// unwatch()
}
}
Vue.createApp(App).mount('#app');
</script>
</body>
</html>
网友评论