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

Vue3监听数据变化方法详解

在 Vue 3 中,监听数据变化主要依赖 watch 和 watchEffect 两个 API,它们都属于 Composition API 的一部分。以下是详细的用法和区别:


一、watch 的基本用法

作用:显式监听特定数据源,在数据变化时执行回调函数。

1. 监听单个数据源

javascript

复制

import { ref, watch } from 'vue';const count = ref(0);// 监听 ref
watch(count, (newVal, oldVal) => {console.log(`count变化: ${oldVal} → ${newVal}`);
});
2. 监听 reactive 对象的属性

javascript

复制

import { reactive, watch } from 'vue';const state = reactive({ user: { name: 'Alice', age: 30 }
});// 监听对象属性(需用 getter 函数)
watch(() => state.user.age,(newVal, oldVal) => {console.log(`年龄变化: ${oldVal} → ${newVal}`);}
);
3. 监听多个数据源

javascript

复制

const a = ref(1);
const b = ref(2);watch([a, b], ([newA, newB], [oldA, oldB]) => {console.log(`a: ${oldA}→${newA}, b: ${oldB}→${newB}`);
});
4. 深度监听(deep)

默认情况下,watch 是浅层监听。对嵌套对象需开启 deep: true

javascript

复制

watch(() => state.user,(newUser) => {console.log('用户信息变化(包括嵌套属性):', newUser);},{ deep: true }
);
5. 立即执行(immediate)

在监听开始后立即触发回调:

javascript

复制

watch(count,(newVal) => {console.log('初始值:', newVal);},{ immediate: true }
);

二、watchEffect 的用法

作用:自动跟踪依赖,并在依赖变化时立即执行副作用函数。

1. 基本使用

javascript

复制

import { ref, watchEffect } from 'vue';const count = ref(0);// 自动追踪 count 的变化
watchEffect(() => {console.log('当前count值:', count.value);
});
2. 自动聚合依赖

无需手动指定依赖,函数内使用的响应式变量会被自动追踪:

javascript

复制

const a = ref(1);
const b = ref(2);watchEffect(() => {console.log('a + b =', a.value + b.value);
});
// 修改 a 或 b 都会触发
3. 清理副作用

通过返回一个函数来清理副作用(如定时器、事件监听):

javascript

复制

watchEffect((onCleanup) => {const timer = setInterval(() => {console.log('每秒执行');}, 1000);onCleanup(() => clearInterval(timer));
});

三、watch vs watchEffect

特性watchwatchEffect
依赖指定显式指定数据源自动追踪回调内的响应式依赖
初始执行默认不执行(可配置 immediate立即执行
适用场景需要精确控制监听的数据源依赖变化时自动执行聚合逻辑
深度监听需手动开启 deep: true自动追踪嵌套属性(类似 deep)

四、停止监听器

通过调用 watch 或 watchEffect 返回的函数来停止监听:

javascript

复制

const stop = watchEffect(() => { /* ... */ });// 停止监听
stop();

在组件卸载时自动停止:

javascript

复制

import { onUnmounted } from 'vue';setup() {const stop = watchEffect(() => { /* ... */ });onUnmounted(stop);
}

五、实用场景示例

1. 搜索输入防抖(watch)

javascript

复制

const searchQuery = ref('');
let timeoutId;watch(searchQuery, (newQuery) => {clearTimeout(timeoutId);timeoutId = setTimeout(() => {fetchResults(newQuery);}, 500);
});
2. 自动保存表单(watchEffect)

javascript

复制

const form = reactive({ title: '', content: '' });watchEffect((onCleanup) => {// 自动追踪 form.title 和 form.contentconst autoSave = setTimeout(() => {saveToServer(form);}, 3000);onCleanup(() => clearTimeout(autoSave));
});

六、注意事项

  1. 避免无限循环:在监听回调中修改被监听的数据可能导致循环,需谨慎。

  2. 性能优化:避免过度使用 deep: true,尤其是大型对象。

  3. 异步操作:在回调中进行异步操作时,使用 onCleanup 清理未完成的请求。

掌握这些技巧后,你可以更灵活地利用 Vue 3 的响应式系统构建高效应用!

相关文章:

  • 详解LeetCode中用字符串实现整数相加,字符串转整数及其溢出处理详解
  • 网络编程(UDP)
  • Flutter 应用在真机上调试的流程
  • HOW - 前端 sdk 实践(一)
  • 如何写好合同管理系统需求分析
  • 软考教材重点内容 信息安全工程师 第22章 网站安全需求分析与安全保护工程
  • 【C++算法】60.哈希表_字母异位词分组
  • PG中通过GIST创建其他自定义索引
  • 深度学习入门:神经网络的学习
  • 入门51单片机(1)-----点灯大师梦开始的地方
  • 网络安全与信息安全的区别​及共通
  • CEPH OSD_SLOW_PING_TIME_FRONT/BACK 警告处理
  • MuJoCo(Multi-Joint Dynamics with Contact)机器人仿真器存在的问题
  • rook-ceph 慢盘导致的 OSD_SLOW_PING_TIME_[BACK/FRONT] 告警分析
  • Elasticvue-轻量级Elasticsearch可视化管理工具
  • 25软考新版系统分析师怎么备考?重点考哪些?(附新版备考资源)
  • G1 垃圾回收机制
  • Formality:Bug记录
  • 空格键会提交表单吗?HTML与JavaScript中的行为解析
  • Serverless MCP 运行时业界首发,函数计算让 AI 应用最后一公里提速
  • “不意外”和“不遗余力”,直击上海商超对接外贸企业
  • 太好玩了!坐进大卫·霍克尼的敞篷车进入他画笔下的四季
  • 非法收受财物逾1648万,湖南原副厅级干部康月林一审被判十年半
  • 《沙尘暴》:用贴近生活的影像和表演拍摄悬疑剧
  • 年客流超2500万,九岁的上海国际旅游度假区有哪些文旅商体实践?
  • 经济日报:AI时代如何寻找“你的赛道”