使用watch来侦听data中数据的变化,watch中的属性一定是data 中已经存在的数据 或者 computed 生成的新属性。
watch可以监听路由中的数据的变化
好想下课呀
上课的时候,有些同学一直盯着手表,监听什么时候下课。
复制Vue.createApp({
...
data() { // 返回一个对象,对象中写初始化数据
return {
time: 0, // 初始化一个的数据
};
},
watch: { // 侦听器的配置
time(cur, pre) { // 监听time是否会发生变化,有两个参数,第一个参数是cur,是time当前的值,另一个是pre,是更新前time的值,可以是异步函数
if (cur >= 45) {
console.log('下课了');
}
}
},
...
});
停止侦听器
如果需要停止侦听器,不能使用选项配置,需要使用实例方法$watch函数。
$watch函数有两个参数,第一个参数是被监听的属性名称,第二个参数是一个函数,和选项配置里面的是一样的。
返回一个停止监听的函数,我们可以调用这个函数停止监听。
复制this.stopWatch = this.$watch('time', (cur, pre) => {
if (cur >= 45) {
console.log('下课了');
}
});
...
this.stopWatch(); // 停止监听
什么时候用选项配置的watch选项,什么时候用$watch()呢?
如果一开始就需要监听数据,建议直接在options Api中添加 watch选项
如果在达到某一个条件下再开启监听,需要使用 this.watch()手动添加侦听器 如果需要停止,一定要用this.watch()手动添加侦听器
配置
如果侦听器需要额外的配置,需要写成对象类型。
.handler
被侦听的数据改变时执行的回调函数,和上面的回调一致。
.immediate
watch默认第一次加载不做监听,如果需要第一次加载做监听,添加immediate属性,设置为true
.deep
默认情况下侦听器侦听的数据是一个对象的话,只侦听这个对象引用的变化,只有在给对象重新赋值一个引用时它才能被监听到。这个对象数据内部的成员、内部对象成员里的成员,都是监听不到的。
如果需要侦听数据内部的成,需要设置 deep为true,设置后那么无论该对象被嵌套的有多深,都会被侦听到。
复制 'student.name': {
handler (cur, pre) {
console.log({ cur, pre });
},
deep: true, // 虽然无论该对象被嵌套的有多深,都会被侦听到,但是对象太大性能消耗也大
// immediate: true, // 如果需要第一次加载做监听时添加
}
watch和computed的区别
watch监听的函数不用返回值,computed有返回值,并依赖函数里面提到的属性,并且生成了一个新属性
computed更像是一种依赖,别人变化,自己就跟着变
watch更主动,主动取监听某一个属性的变化
computed支持缓存,相依赖的数据发生改变才会重新计算;watch不支持缓存,只要监听的数据变化就会触发相应操作
computed不支持异步,当computed内有异步操作时是无法监听数据变化的;watch支持异步操作
复制Vue.createApp({
data() { // 返回一个对象,对象中写初始化数据
return {
day: 0, // 初始化一个的数据
};
},
computed: { // 计算属性的配置
leftDay() { // 定义一个名叫leftDay的计算属性,他和普通属性一致,只是写操作会被警告
return 90 - this.day; // 根据其他属性计算得到结果
}
},
...
});
watch和computed在哪些情况下使用
计算属性擅长处理的场景是:多个数据影响一个数据 ----购物车商品结算。
watch擅长处理的场景是:一个数据变化影响多个数据。----搜索框.
watch 数据变化时执行异步或开销比较大的操作
TIP:如果有一个人在睡觉,你也会跟着睡觉。用computed
TIP: 如果你发现老师来了,你就告诉大家不要睡觉了。用watch
实例
- 还有多少分钟下课
- 记录值的变化过程从pre变到cur,用log list显示出来