Vue3的watch,你们都手动清除过吗?

程序员咋不秃头 2025-04-14 01:00:27

在 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.jsimport { watch } from'vue'import store from'./store'// 全局监听(危险操作!)let globalWatcher = nullexportfunction 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, () => {})

扩展性:封装重启功能,增强可维护性。

0 阅读:13