当前位置: 首页 > news >正文

Vue中的监听方式

一、为什么需要“监听”?

先思考一个问题:Todo 应用中,当 todos 数组变化时(添加/删除/修改待办),doneCount(已完成数量)会自动更新,这是因为 doneCount计算属性(computed),它依赖 todos 并自动响应变化。

但如果我们需要在 todos 变化时做更复杂的事情,比如:

  • 打印日志到控制台
  • 本地存储(localStorage)保存数据(刷新页面不丢失)
  • 满足某个条件时弹窗提示(如“已完成所有待办!”)
  • 此时计算属性computed已经不够用了,因为computed只能利用一个已知值计算新值,不能执行这些副作用(日志、存储、弹窗),这时候监听功能登场

二、Vue 中的监听方式

vue2基本语法

export default{
data(){
return {
todos:[],//要监听的数组
count:0//要监听的数字
}};},
//监听配置
watch:{
//监听data中的count变量
count(newVal,oldVal)
//newVal是变化后的新值,oldVal是变化前的旧值 
console.log('count从${oldVal} 变成了 ${newVal}');
},
//监听对象或数组
todos:{
handler(newVal, oldVal) { // 监听函数(必须叫 handler)
//列如变化时保存到LOCALstorage
localStorage.setltem('todos', JSON.stringify(newVal));
},
deep:true,//深度监听:对象/数组内部属性变化时也触发(默认值监听也能用变化)
immediate;true//初始化时立即执行一次监听函数(默认旨在数据变化时执行
}
}
};

关键点

  • 监听简单类型(数字、字符串、布尔值):直接写变量名(newVal,oldval)(````}
  • 监听对象/数组:需要队形形式,指定handler函数,并设置deep:true(否则数组元素变化、对象属性变化不会触发监听)
  • immediate:true:页面加载是立即执行一次监听函数(比如初始化时从localStorage读取数据)
Vue3 组合式 API:watch 和 watchEffect(推荐写法)

在 Vue3 的 <script setup> 中,需要从 Vue 导入 watchwatchEffect 函数使用,更灵活、更贴近 JavaScript 原生逻辑。

(1) watch:精确监听(指定监听源,类似 Vue2 的 watch)

基本语法


<script setup>import {ref,watch}from 'vue'//d定义响应式变量ocnst count=ref(0);const user=ref({name:'Tom',age:20});//1、监听ref基本类型(count)watch(count,(newVal,oldVal)=>{console.log('count变化了:${oldVal} → ${newVal}`);});//2|监听ref对象的某个属性(需要函数返回要监听的属性watch(()=>user.value.age,//监听源,返回user.age(newAge,oldAge)=>{console.log('年龄变化率:${oldAge} → ${newAge}');},{ deep: false, immediate: false } // 可选配置(deep/immediate,默认 false));// 3. 监听多个源(数组形式)
watch([count, () => user.value.age], // 同时监听 count 和 user.age([newCount, newAge], [oldCount, oldAge]) => {console.log(`count: ${oldCount}→${newCount}, age: ${oldAge}→${newAge}`);}
);
</script>

核心特点

  • 需显式指定监听源:第一个参数是“监听源”(可以是 ref 变量、返回值的函数、数组等)。
  • 能获取新旧值:第二个参数是回调函数,接收 newVal 和 oldVal
  • 可配置 deep 和 immediate:第三个参数是配置对象(和 Vue2 的 watch 选项一致)。
(2) watchEffect:自动追踪依赖(更简洁,适合“副作用”场景)

watchEffect 是 Vue3 新增的“智能监听”,它会 自动追踪函数内部使用的所有响应式变量,当这些变量变化时,函数会重新执行。

基本语法

<script setup>
import { ref, watchEffect } from 'vue';const count = ref(0);
const user = ref({ name: 'Tom', age: 20 });// 自动监听函数内部用到的所有响应式变量(count 和 user.age)
const stop = watchEffect(() => {console.log(`count: ${count.value}, age: ${user.value.age}`);// 例:保存到本地存储(副作用)localStorage.setItem('count', count.value);localStorage.setItem('age', user.value.age);
});// 停止监听(需要时调用,比如组件卸载前)
// stop(); 
</script>

核心特点

  • 无需指定监听源:函数内部用到哪个响应式变量(如 count.valueuser.value.age),就自动监听哪个变量。
  • 默认 immediate: true:初始化时立即执行一次,之后依赖变化时再执行。
  • 无法获取 oldVal:只能拿到新值(因为它追踪的是“当前依赖的状态”,不是“变化过程”)。
  • 返回停止函数:调用返回的 stop() 可以手动停止监听(适合临时监听场景)。

实战案例:给 Todo 应用添加“本地存储”功能

我们用 watchEffectwatch 实现 “Todo 待办数据持久化”(刷新页面后数据不丢失),步骤如下:

Step 1:初始化时从 localStorage 读取数据

todos 初始化时,先检查本地存储是否有保存的数据,如果有就加载,没有就用默认数据:

<script setup>
import { ref, watchEffect } from 'vue';// 初始化 todos:优先从 localStorage 读取,没有则用默认数据
const savedTodos = localStorage.getItem('todos');
const todos = ref(savedTodos ? JSON.parse(savedTodos) : [{ text: '学习 Vue watch', done: false },{ text: '掌握 watchEffect', done: true }
]);
</script>

步骤②:用watchEffect监听todos变化并保存

watchEffect会自动追踪todos.value的变化,当todos数组添加/删除/修改时,自动保存到localStorage:

<script setup>
// ... 其他变量(inputText、editingIndex 等)...// ✅ 监听 todos 变化,自动保存到本地存储
watchEffect(() => {// 每次 todos 变化时执行(包括初始化)localStorage.setItem('todos', JSON.stringify(todos.value));console.log('数据已保存到本地存储');
});
</script>
效果验证
  1. 运行 Todo 应用,添加/删除/修改待办事项。
  2. 按 F12 打开浏览器“开发者工具”→ Application → Local Storage → 查看当前网站的存储,会看到 todos 字段已经保存了数组数据。
  3. 刷新页面 → 待办数据不会丢失,因为初始化时会从 localStorage 读取并加载。

五、进阶案例:条件监听(满足条件时弹窗)

实现“当已完成数量等于总数量时”,弹窗提示“恭喜完成所有待办”,用watch监听doneCount和todos.length

<script setup>
import { ref, computed, watch } from 'vue';// ... todos 定义 ...// 已完成数量(计算属性)
const doneCount = computed(() => todos.value.filter(todo => todo.done).length);// ✅ 监听 doneCount 和 todos.length 的变化
watch([doneCount, () => todos.value.length], // 监听源:已完成数量和总数量([newDone, newTotal], [oldDone, oldTotal]) => {// 条件:总数量 > 0 且 已完成数量 === 总数量if (newTotal > 0 && newDone === newTotal) {alert('恭喜完成所有待办!🎉');}}
);
</script>

逻辑解析

  • doneCount 是计算属性(已完成数量),todos.value.length 是总数量。
  • 当两者相等且总数量 > 0 时,说明所有待办都已完成,触发弹窗。

六、总结:监听功能核心知识点

1、作用:监控数据变化并执行副作用(日志、存储、请求、弹窗等)

2、VUE2写法:watch选项,支持deep、immediate配置,适合OPtion API

3、VUE3写法:

  • watch:精准监听,能获取新旧值,适合需要控制监听源或获取旧值的场景
  • watchEffect:自动追踪依赖,简洁高效,适合只需要执行副作用的场景

4、实战场景:本地存储持久化、数据变化时发请求、条件触发提示等

http://www.dtcms.com/a/392198.html

相关文章:

  • CentOS 7系统解决yum报错
  • GD32VW553-IOT V2开发版【温湿度检测】
  • Perplexica - 开源AI搜索引擎,让搜索更智能
  • Windows在VSCode Cline中安装Promptx
  • 深入解析 Spring AI 系列:解析返回参数处理
  • LeetCode:34.合并K个升序链表
  • 精细化关键词优化:提升SEO效果的长尾策略解析
  • Go基础:Go语言详细介绍,环境搭建,及第一个程序详解
  • 【开题答辩全过程】以 HL新闻为例,包含答辩的问题和答案
  • docker运行wonderShaper实现网卡限速
  • Windows 安装 Docker Desktop 到 D 盘完整教程(含迁移方案)
  • 基于陌讯AI检测算法本地化部署教程:基于Docker的环境配置与性能测试
  • Docker Docker Compose 完整入门与实用技巧
  • ARP协议工作原理分析(基于Wireshark)
  • CKS-CN 考试知识点分享(14) Istio网络策略
  • TCP 协议全解析:握手、挥手、重传与流控的深度剖析
  • 计算机视觉(opencv)实战二十七——目标跟踪
  • 深度学习中神经网络与损失函数优化
  • 整体设计 完整的逻辑链条 之1 点dots/线lines/面faces 的三曲:三进三出的三个来回
  • 微调基本理论
  • LeetCode算法日记 - Day 48: 课程表II、火星词典
  • 【面板数据】地级市中国方言多样性指数数据集
  • C++编程学习(第35天)
  • SS443A 霍尔效应传感器:高性能磁感应解决方案
  • MIT新论文:数据即上限,扩散模型的关键能力来自图像统计规律,而非复杂架构
  • GitHub 热榜项目 - 日榜(2025-09-20)
  • 怎么判断 IP是独享的
  • Linux多进程编程(上)
  • 如何在Spring Boot项目中添加自定义的配置文件?
  • 【MySQL初阶】01-MySQL服务器和客户端下载与安装