是Vue提供的一种更通用的方式来观察和响应Vue实列上的数据变动,在某些情况下,我们希望在代码逻辑中监听某个数据的变化,这个时候就需要用侦听器watch来完成。
<template id="my-app">
<input v-model="message"/>
template>
<script src="../js/vue.js">script>
<script>
const App = {
template:'#my-app',
data() {
return {
message : "hello world"
}
},
watch: {
message(){
console.log(this.message);
}
}
}
Vue.createApp(App).mount("#app")
script>
当我们点击(改变info.name)按钮的时候会修改info.name的值;但是这个时候我们使用watch来侦听info,是侦听不到的!是因为默认情况下,watch只是在侦听info的引用变化,对于内部属性的变化是不会做出响应的:
这个时候我们可以使用一个选项deep进行更深层的侦听!
tips:当变更(不是替换)对象或数组并使用 deep 选项时,旧值将与新值相同,因为它们的引用指向同一个对象/数组。Vue 不会保留变更之前值的副本。
vue3watch
<template id="my-app">
<div>{
{info}}div>
<button @click="changeInfo">改变Infobutton>
<button @click="changeInfoName">改变Info.namebutton>
template>
<script>
const App = {
template:'#my-app',
data() {
return {
info:{
name:"jack",
age:18
}
}
},
watch: {
// 默认情况下我们的侦听器只会针对监听的数据本身的改变(内部发生的改变是不能监听的)
// 当只有handler函数时vue语法糖的写法
// info:function(newInfo,oldInfo){
// console.log("新:",newInfo,"旧:",oldInfo);
// },
info:{
handler:function(newInfo,oldInfo){
//注意:如果改变内部的值打印出来的旧值是和新值一样,
// 是因为vue对于旧值没有做深拷贝,导致所指向的是同一个
// 地址(当数据进行改变时旧数据就和新数据同步了)如需获取旧值,需要自己先拷贝一份数据
console.log("新:",newInfo,"旧:",oldInfo);
},
//当watch里的数据为对象时可以调用更多的属性,当deep为true时开启深度监听,才能监听到数据的内部改变
deep:true, //深度侦听
}
},
methods: {
changeInfo(){
this.info = {
name:'tom'}
},
changeInfoName(){
this.info.name = 'tom2'
},
},
}
Vue.createApp(App).mount("#app")
script>
如果希望一开始的就会立即执行一次: 这个时候我们可以使用immediate选项,无论后面数据是否有变化,侦听的函数都会执行一次
info:{
handler:function(newInfo,oldInfo){
console.log("新:",newInfo,"旧:",oldInfo);
},
deep:true, //深度侦听
immediate:true //立即执行(一定会执行一次)一进页面,无操作也会执行一次
}
在created的生命周期中,可以使用 this.$watchs 来侦听
- 第一个参数是要侦听的源
- 第二个参数是侦听的回调函数callback
- 第三个参数是额外的其他选项,比如deep、immediate
created() {
this.$watch("info",function(newInfo,oldInfo){
console.log(newInfo,oldInfo);
},{
deep:true,
immediate:true
})
}
$watch 返回一个取消侦听函数,用来停止触发回调:
const unwatch = this.$watch("info",function(newInfo,oldInfo){
console.log(newInfo,oldInfo);
},{
deep:true,
immediate:true
})
unwatch() //取消监听