文章目录
-
- 一、什么是watchEffect?
- 二、工作原理
- 三、核心特性
- 四、实战用法示例
-
- [4.1 基础用法(修改页面标题)](#4.1 基础用法(修改页面标题))
- [4.2 自动清理副作用](#4.2 自动清理副作用)
- [4.3 手动停止侦听](#4.3 手动停止侦听)
- 五、与watch的核心区别
- 六、常见避坑点
- 七、核心总结
一、什么是watchEffect?
watchEffect是Vue3组合式API提供的响应式侦听器,用于监听响应式数据变化并执行副作用逻辑。核心定义:立即执行一次副作用函数,自动追踪函数内访问的响应式数据,当依赖变化时重新执行函数,无需手动指定监听源。
它是watch的"简化版",专注于"副作用响应",解决了watch需手动指定依赖的繁琐问题。
二、工作原理
基于Vue3响应式系统的ReactiveEffect实现:
-
执行watchEffect传入的副作用函数,此时会触发响应式数据的getter
-
自动收集函数内访问的所有响应式依赖(依赖追踪)
-
当依赖变化时,触发setter,重新执行副作用函数
-
组件卸载时,自动停止侦听,避免内存泄漏
三、核心特性
-
自动收集依赖:无需像watch那样手动指定监听源,函数内用到的响应式数据都会被追踪
-
立即执行:默认首次渲染就执行一次,无需配置immediate
-
自动清理:支持通过onInvalidate清理副作用(如移除事件监听、取消请求)
-
自动停止:在
四、实战用法示例
4.1 基础用法(修改页面标题)
javascript
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
// 自动追踪count,count变化时重新执行
watchEffect(() => {
document.title = `当前计数:${count.value}`
})
</script>
4.2 自动清理副作用
javascript
<script setup>
import { watchEffect } from 'vue'
watchEffect((onInvalidate) => {
// 绑定事件监听
const handleClick = () => console.log('点击事件')
document.addEventListener('click', handleClick)
// 依赖变化/组件卸载前清理
onInvalidate(() => {
document.removeEventListener('click', handleClick)
})
})
</script>
4.3 手动停止侦听
javascript
<script setup>
import { ref, watchEffect } from 'vue'
const count = ref(0)
// watchEffect返回停止函数
const stop = watchEffect(() => {
console.log('count值:', count.value)
})
// 满足条件时停止侦听
if (count.value > 5) {
stop()
}
</script>
五、与watch的核心区别
| 对比维度 | watchEffect | watch |
|---|---|---|
| 依赖收集 | 自动收集函数内依赖 | 需手动指定监听源 |
| 触发时机 | 默认立即执行 | 默认惰性执行(需immediate开启) |
| 旧值获取 | 不支持 | 支持(newVal, oldVal) |
| 适用场景 | 动态依赖、简单副作用 | 旧值对比、节流防抖、异步请求 |
六、常见避坑点
-
副作用堆积:未清理副作用(如事件监听、定时器),导致多次执行后重复绑定,需用onInvalidate清理
-
依赖未追踪:函数内未直接访问响应式数据(如嵌套过深未触发getter),需确保依赖被直接访问
-
异步逻辑问题:异步操作内的响应式数据不会被追踪,需将依赖写在同步代码中
七、核心总结
watchEffect核心价值是"简化响应式侦听",无需手动指定依赖,适合动态依赖、简单副作用场景(如DOM操作、页面标题修改、临时调试)。记住3个关键点:
-
自动收集依赖,无需手动配置监听源
-
首次立即执行,依赖变化重新执行
-
必做:用onInvalidate清理副作用,避免内存泄漏
与watch互补使用,简单副作用用watchEffect,需旧值对比、异步节流用watch,高效驾驭Vue3响应式侦听。