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

www.jswusn.com Other 2025-04-09 10:07:36 8次浏览

在 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, () => {})

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

技术分享

苏南名片

  • 联系人:吴经理
  • 电话:152-1887-1916
  • 邮箱:message@jswusn.com
  • 地址:江苏省苏州市相城区

热门文章

Copyright © 2018-2025 jswusn.com 版权所有

技术支持:苏州网站建设  苏ICP备18036849号