如何停止监听呢?
下面分两种情况进行讲解
情况一
情况一是使用回调函数,停止事件监听
TypeScript
<!-- 这个界面就是花上的叶子,要在App中引入,把叶子装在枝干上 -->
<template>
<div class="person">
<h1>【情况一:监视ref定义的基本类型数据】</h1>
<h2 @click="changeSum">当前求和为:{{ sum }}</h2>
</div>
</template>
<script lang="ts" setup name="Person">
// 导入
import { ref, watch } from 'vue'
// 数据
let sum = ref(0)
// 方法
function changeSum() {
sum.value++
}
// 监视
const stopWatch = watch(sum, (newValue, oldValue) => {
console.log(`sum的值发生了改变, 新:${newValue},旧值:${oldValue}`)
if(newValue > 5) {
stopWatch()
}
})
console.log(stopWatch)
//可以看看打印的结果,运行界面之后按F12,打开控制台可进行查看
//
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
border-radius: 10px;
padding: 20px;
}
</style>
内容讲解
上面给sum值添加了一个监听,那如何停止监听呢?
就是给watch执行了一个回调函数
在这个代码中,开始时
watch
对count
进行监听,每次count
的值改变,回调函数就会执行并打印变化信息。但当count
的值达到5
或者更大时,stopWatch
函数被调用,此时 Vue 内部会依据这个调用执行相应的清理工作,解除对count
后续变化的监听关系,之后哪怕count
的值再怎么改变,也不会执行这个watch
对应的回调函数了,实现了停止监听的目的。所以,
stopWatch
函数本质上是 Vue 提供的用于手动控制watch
监听生命周期的一个工具,方便开发者根据业务逻辑需求灵活决定何时停止对特定数据变化的关注和响应内部实现机制
watch
函数内部其实维护了一套用于观察和响应数据变化的逻辑,它会在你传入要监听的数据(比如ref
定义的响应式数据或者reactive
定义的响应式对象等)后,通过 Vue 的响应式系统来追踪这些数据的变化情况。当数据发生变化时,就会触发对应的回调函数执行相应的操作。而返回的这个
stopWatch
函数,实际上是一个关闭这个特定监听任务的接口。当watch
开始监听时,它会创建一个内部的订阅者对象或者类似的结构(具体是内部的实现细节,但可以简单这么理解)来负责检测数据变化并触发回调。这个stopWatch
函数被调用时,它会在内部执行一些清理操作,比如移除与这个监听相关的事件订阅、取消对数据变化的追踪关联等,从而使得后续这个被监听的数据即便再发生变化,也不会再触发对应的回调函数了,也就是实现了停止监听的效果。类比理解
可以把
watch
的监听过程想象成你订阅了一份报纸(数据变化就是有新的消息更新),每天送报员(Vue 的响应式系统)会查看报纸有没有新内容(数据有没有变化),如果有就会给你送过来(触发回调函数)。而stopWatch
函数就好比你打电话给报社说 "我不想再订阅了"(调用stopWatch
),报社接到通知后(内部进行清理操作),就不会再安排送报员给你送报纸了(不再追踪数据变化触发回调),你也就不会再接收到后续的报纸(不会再响应数据变化了)。
情况二
情况二是调用函数进行暂停,恢复和停止时间监听
TypeScript
<template>
<div class="Test">
<h1>Watch示例 - 暂停、恢复与停止监听演示</h1>
<p>当前计数: {{ count }}</p>
<button @click="increment">增加计数</button>
<button @click="decrement">减少计数</button>
<button @click="pauseWatch">暂停监听</button>
<button @click="resumeWatch">恢复监听</button>
<button @click="stopWatch">停止监听</button>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
// 创建响应式数据,用于存储计数器的值,初始值为0
const count = ref(0);
// 用于存储watch实例,后续通过它来调用pause、resume、stop方法
let watchInstance;
// 定义watch监听计数变化,当计数变化时打印相关信息
watchInstance = watch(count, (newValue, oldValue) => {
console.log(`计数从 ${oldValue} 变为 ${newValue}`);
});
// 增加计数的方法
const increment = () => {
count.value++;
};
// 减少计数的方法
const decrement = () => {
count.value--;
};
// 暂停监听的方法
const pauseWatch = () => {
watchInstance.pause();
console.log('已暂停对计数变化的监听');
};
// 恢复监听的方法
const resumeWatch = () => {
watchInstance.resume();
console.log('已恢复对计数变化的监听');
};
// 停止监听的方法
const stopWatch = () => {
watchInstance.stop();
console.log('已停止对计数变化的监听,后续计数变化将不再触发监听回调');
};
</script>
<style scoped>
.Test {
text-align: center;
padding: 20px;
background-color: #faebeb;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
button {
margin: 5px 10px;
padding: 8px 15px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: white;
cursor: pointer;
}
</style>
模板部分(
<template>
)
展示了一个简单的页面结构,包含显示当前计数的文本、用于增加计数和减少计数的按钮,以及分别对应暂停监听、恢复监听和停止监听的按钮,方便用户操作并观察不同操作对监听的影响。
脚本部分(
<script setup>
)
- 响应式数据与
watch
监听初始化 :
- 通过
ref
创建了count
这个响应式数据,初始值设为0
,用于模拟计数器的值。- 使用
watch
监听count
的变化,每当count
的值发生改变,回调函数就会执行并在控制台打印出计数变化的前后值,如计数从 1 变为 2
这样的信息,同时将watch
实例赋值给watchInstance
变量,以便后续调用其相关方法。- 操作计数的方法 :
分别定义了increment
和decrement
方法,用于增加和减少count
的值,通过点击页面上对应的按钮可以改变count
的值,从而触发watch
的监听回调(在未暂停、停止监听的情况下)。- 暂停、恢复和停止监听的方法 :
pauseWatch
方法:调用watchInstance.pause()
来暂停对count
变化的监听,并且在控制台打印提示信息告知用户已暂停监听,此后再改变count
的值,watch
的回调函数不会被触发执行,直到调用resumeWatch
方法恢复监听。resumeWatch
方法:调用watchInstance.resume()
来恢复之前被暂停的对count
变化的监听,同时在控制台打印相应提示信息,恢复后,若count
的值再次改变,watch
的回调函数又会正常执行了。stopWatch
方法:调用watchInstance.stop()
彻底停止对count
变化的监听,打印提示信息说明后续计数变化将不再触发监听回调,意味着之后无论怎么改变count
的值,watch
对应的回调函数都不会再执行了,监听关系被完全解除。
这个就是console.log()的watchStop
