vue3watch的停止监视分析

如何停止监听呢?

下面分两种情况进行讲解

情况一

情况一是使用回调函数,停止事件监听

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执行了一个回调函数

在这个代码中,开始时 watchcount 进行监听,每次 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 变量,以便后续调用其相关方法。
  • 操作计数的方法
    分别定义了 incrementdecrement 方法,用于增加和减少 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
相关推荐
十八朵郁金香1 小时前
【JavaScript】深入理解模块化
开发语言·javascript·ecmascript
m0_748230941 小时前
Redis 通用命令
前端·redis·bootstrap
YaHuiLiang1 小时前
一切的根本都是前端“娱乐圈化”
前端·javascript·代码规范
菜鸟一枚在这2 小时前
深入解析设计模式之单例模式
开发语言·javascript·单例模式
ObjectX前端实验室3 小时前
个人网站开发记录-引流公众号 & 谷歌分析 & 谷歌广告 & GTM
前端·程序员·开源
CL_IN3 小时前
企业数据集成:实现高效调拨出库自动化
java·前端·自动化
浪九天4 小时前
Vue 不同大版本与 Node.js 版本匹配的详细参数
前端·vue.js·node.js
qianmoQ4 小时前
第五章:工程化实践 - 第三节 - Tailwind CSS 大型项目最佳实践
前端·css
C#Thread5 小时前
C#上位机--流程控制(IF语句)
开发语言·javascript·ecmascript
尚学教辅学习资料5 小时前
基于SpringBoot+vue+uniapp的智慧旅游小程序+LW示例参考
vue.js·spring boot·uni-app·旅游