Vue3 Composition API 实战:watchEffect 自动追踪依赖的实战用法

Vue3 的 Composition API 引入了 watchEffect 函数,它能自动追踪响应式依赖,并在依赖变化时自动执行副作用函数。这简化了代码逻辑,避免了手动指定依赖的繁琐。下面我将逐步解释其核心机制、实战用法和注意事项,确保内容基于官方文档和最佳实践。

1. watchEffect 的核心机制
  • 自动依赖追踪watchEffect 接受一个函数作为参数(称为“副作用函数”)。在首次执行时,它会自动收集函数中访问的所有响应式属性(如 refreactive 对象)作为依赖。当这些依赖变化时,函数会自动重新运行。
  • watch 的区别watch 需要显式指定依赖列表,而 watchEffect 无需手动声明,依赖由系统自动推断,这减少了代码冗余。
  • 立即执行watchEffect 在初始化时立即运行一次副作用函数,确保初始状态被处理。
2. 实战用法示例

下面通过几个常见场景展示 watchEffect 的实战应用。所有代码基于 Vue3 的 Composition API,在 setup() 函数中使用。

场景 1:基本计数器(自动追踪单个依赖)
当计数器的值变化时,自动更新页面标题。

import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const count = ref(0); // 响应式变量
    
    // watchEffect 自动追踪 count 的变化
    watchEffect(() => {
      document.title = `Count: ${count.value}`; // 副作用:更新标题
    });

    return { count };
  }
};

  • 说明count.value 被访问,因此 count 成为自动依赖。当 count 变化时,document.title 会自动更新。

场景 2:数据获取(自动追踪多个依赖)
当用户 ID 或过滤条件变化时,自动从 API 获取数据。

import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const userId = ref(1);
    const filter = ref('active');
    const userData = ref(null);
    
    // watchEffect 自动追踪 userId 和 filter 的变化
    watchEffect(async (onInvalidate) => {
      const controller = new AbortController();
      const signal = controller.signal;
      
      // 清理上一次的请求(避免竞态条件)
      onInvalidate(() => controller.abort());
      
      try {
        const response = await fetch(`https://api.example.com/users/${userId.value}?filter=${filter.value}`, { signal });
        userData.value = await response.json();
      } catch (error) {
        if (error.name !== 'AbortError') {
          console.error('Fetch failed:', error);
        }
      }
    });

    return { userId, filter, userData };
  }
};

  • 说明userId.valuefilter.value 被访问,因此两者都成为依赖。onInvalidate 用于清理副作用(如取消请求),防止旧请求覆盖新结果。

场景 3:计算属性联动(自动追踪嵌套依赖)
当表单输入变化时,自动计算并显示结果。

import { ref, reactive, watchEffect } from 'vue';

export default {
  setup() {
    const form = reactive({ name: '', age: 0 });
    const summary = ref('');
    
    // watchEffect 自动追踪 form.name 和 form.age 的变化
    watchEffect(() => {
      summary.value = `Name: ${form.name}, Age: ${form.age}`;
    });

    return { form, summary };
  }
};

  • 说明form.nameform.age 是响应式属性,watchEffect 自动收集它们。当表单输入变化时,summary 实时更新。
3. 注意事项与最佳实践
  • 副作用清理:使用 onInvalidate 参数来注册清理函数(如取消定时器或网络请求),避免内存泄漏或竞态问题。
  • 性能优化:如果副作用函数开销大,考虑使用 watch 显式指定依赖,或使用 { flush: 'post' } 选项延迟执行到 DOM 更新后。
  • 避免无限循环:不要在副作用函数中修改依赖(如 count.value++),否则会导致递归更新。如果必须修改,使用条件判断。
  • 调试技巧:在开发模式下,Vue Devtools 可以显示 watchEffect 的依赖列表,帮助定位问题。
  • 适用场景watchEffect 适合自动响应的场景(如日志、UI 同步),而 watch 更适合精确控制(如深度监听特定路径)。
4. 总结

watchEffect 是 Vue3 Composition API 的强大工具,通过自动追踪依赖,简化了响应式编程。它特别适合处理副作用逻辑(如数据获取、DOM 操作),减少样板代码。实战中,结合 onInvalidate 清理机制,可以构建高效、健壮的应用程序。建议在项目中优先使用 watchEffect 替代部分 watch 场景,以提升开发效率。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐