马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
watch
在 Vue 3 的 Composition API 中,watch 和 watchEffect 是用于相应式侦听数据厘革的核心 API。它们都能追踪依靠并实行副作用,但在利用方式和场景上有明显差异。以下是详细分析:
watch 和 watchEffect 对比
特性watchwatchEffect依靠网络方式显式指定侦听的数据源自动网络回调函数内的相应式依靠立刻实行默认不立刻实行(可通过 immediate: true 开启)总是立刻实行旧值访问可获取旧值(oldValue)无法获取旧值实用场景必要正确控制侦听目的依靠多个数据或必要自动追踪依靠的场景 watch 的深度分析
1. 根本语法
- import { watch, ref } from 'vue';
- const count = ref(0);
- // 监听单个 ref
- watch(count, (newVal, oldVal) => {
- console.log(`count变化:${oldVal} → ${newVal}`);
- });
- // 监听多个源(数组形式)
- watch([count, otherRef], ([newCount, newOther], [oldCount, oldOther]) => {
- // 处理多个变化
- });
复制代码 2. 监听差异范例的数据源
- Ref 范例:
- const num = ref(0);
- watch(num, (newVal) => { /* ... */ });
复制代码 - Reactive 对象属性:
- const state = reactive({ user: { name: 'Alice' } });
- watch(
- () => state.user.name, // 使用 getter 函数
- (newName) => { /* ... */ }
- );
复制代码 - 深层监听对象/数组:
- watch(
- () => state.user,
- (newUser) => { /* ... */ },
- { deep: true } // 深度监听嵌套属性变化
- );
复制代码 3. 设置选项
选项分析deep: true深度监听对象/数组的内部厘革immediate: true立刻触发回调(雷同 Vue 2 的 immediate)`flush: ‘pre’‘post’- watch(
- source,
- callback,
- { deep: true, immediate: true, flush: 'post' }
- );
复制代码 watchEffect 的深度分析
1. 根本用法
- import { watchEffect, ref } from 'vue';
- const count = ref(0);
- // 自动追踪依赖
- watchEffect(() => {
- console.log(`count的值:${count.value}`);
- });
- count.value = 1; // 输出 "count的值:1"
复制代码 2. 特点
- 自动依靠追踪:回调函数中利用的相应式变量会被自动追踪。
- 立刻实行:初始化时立刻运行一次。
- 无需指定依靠:得当依靠多个相应式变量的场景。
3. 克制侦听器
通过调用返回的函数克制侦听:- const stop = watchEffect(() => { /* ... */ });
- stop(); // 手动停止侦听
复制代码 4. 清算副作用
在回调中返回一个清算函数,用于重置操纵(如取消哀求):- watchEffect((onCleanup) => {
- const timer = setTimeout(() => {
- // 异步操作
- }, 1000);
- onCleanup(() => clearTimeout(timer)); // 清理函数
- });
复制代码 利用场景对比
1. 利用 watch 的场景
- 必要正确控制侦听的目的。
- 必要获取旧值举行比力。
- 必要耽误实行(默认不立刻实行)。
- 必要深度监听对象/数组。
2. 利用 watchEffect 的场景
- 依靠多个相应式变量且不想逐个指定。
- 必要立刻实行回调(如初始化加载数据)。
- 逻辑简朴且依靠关系动态厘革。
最佳实践与注意事项
1. 制止无穷循环
在回调中修改被侦听的源数据大概导致无穷循环:- // ❌ 错误示例
- watch(count, (newVal) => {
- count.value = newVal * 2; // 触发再次侦听
- });
复制代码 2. 性能优化
- 淘汰深度监听:deep: true 对性能有影响,只管明确侦听详细属性。
- 公道利用 flush:flush: 'post' 可确保回调在 DOM 更新后实行。
3. 异步操纵处置惩罚
- 利用 onCleanup 清算未完成的异步任务(如哀求取消):
- watchEffect(async (onCleanup) => {
- const abortController = new AbortController();
- onCleanup(() => abortController.abort()); // 清理时取消请求
- const data = await fetch(url, {
- signal: abortController.signal
- });
- });
复制代码
完备示例
示例 1:监听搜刮关键词(防抖)
- <script setup>
- import { ref, watch } from 'vue';
- const searchKeyword = ref('');
- let timer = null;
- watch(searchKeyword, (newKeyword) => {
- clearTimeout(timer);
- timer = setTimeout(() => {
- fetchResults(newKeyword); // 防抖处理
- }, 500);
- });
- </script>
复制代码 示例 2:自动追踪窗口尺寸
- <script setup>
- import { watchEffect } from 'vue';
- const windowWidth = ref(window.innerWidth);
- watchEffect((onCleanup) => {
- const handleResize = () => {
- windowWidth.value = window.innerWidth;
- };
- window.addEventListener('resize', handleResize);
- onCleanup(() => {
- window.removeEventListener('resize', handleResize);
- });
- });
- </script>
复制代码 API核心选择依据watch必要明确侦听特定命据源,获取旧值,或必要耽误实行、深度监听时利用watchEffect依靠多个动态数据源,必要立刻实行,或依靠关系复杂时利用 |