在 Vue3 的响应式系统中,watch 是监听数据变化的核心 API 之一。随着 Composition API 的普及,开发者需要更清晰地理解副作用管理机制
一、Vue3 的 watch 机制
1.1 基本用法
import { ref, watch } from 'vue' const count = ref(0) // 基本监听模式 const stopWatch = watch(count, (newVal, oldVal) => { console.log(`值从 ${oldVal} 变为 ${newVal}`) }) // 停止监听 // stopWatch() // 手动调用停止监听
1.2 自动停止机制
当在组件 setup() 中同步创建时,Vue3 会自动关联生命周期:
export default { setup() { const count = ref(0) // 自动绑定组件生命周期 watch(count, (val) => { console.log('Count changed:', val) }) return { count } } }
组件卸载时,Vue 会自动停止这些监听器,无需手动干预
二、必须手动清除的 3 种场景
2.1 异步创建的监听器
import { onMounted, onUnmounted } from'vue' exportdefault { setup() { let stopWatch = null onMounted(() => { // 异步创建监听器 setTimeout(() => { stopWatch = watch(/* ... */) }, 1000) }) onUnmounted(() => { if (stopWatch) { stopWatch() // 必须手动清除 } }) } }
关键点:Vue 无法追踪异步创建的监听器,需要开发者自行管理
2.2 动态条件监听
const searchKeyword = ref('') let searchWatch = null // 根据用户操作动态创建 function enableSearch() { searchWatch = watch(searchKeyword, () => { // 执行搜索逻辑 }) } function disableSearch() { searchWatch?.() // 主动销毁 }
典型场景:需要运行时动态启用的监听逻辑
2.3 全局状态监听
// store.js import { watch } from'vue' import store from'./store' // 全局监听(危险操作!) let globalWatcher = null exportfunction initGlobalWatch() { globalWatcher = watch( () => store.state.user, (user) => { console.log('User changed:', user) } ) } exportfunction cleanupGlobalWatch() { globalWatcher?.() }
风险提示:全局监听器不会自动销毁,必须提供显式清理接口
三、智能管理方案
3.1 自动管理组合式函数
import { watchEffect, onScopeDispose } from'vue' exportfunction useAutoCleanWatcher() { const stop = watchEffect(() => { // 副作用逻辑 }) // 自动注册清理 onScopeDispose(() => { stop() }) return { stop } }
优势:利用 onScopeDispose 实现自动清理
3.2 监听器工厂模式
function createSmartWatcher(source, callback) { const stop = watch(source, callback) return { stop, restart: () => { stop() return createSmartWatcher(source, callback) } } } // 使用示例 const { stop } = createSmartWatcher(value, () => {})
扩展性:封装重启功能,增强可维护性