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

开发 前端
在 Vue3 的响应式系统中,watch 是监听数据变化的核心 API 之一。随着 Composition API 的普及,开发者需要更清晰地理解副作用管理机制。

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心~

在 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.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

1.2 自动停止机制

当在组件 setup() 中同步创建时,Vue3 会自动关联生命周期:

export default {
  setup() {
    const count = ref(0)
    
    // 自动绑定组件生命周期
    watch(count, (val) => {
      console.log('Count changed:', val)
    })

    return { count }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

组件卸载时,Vue 会自动停止这些监听器,无需手动干预

二、必须手动清除的 3 种场景

2.1 异步创建的监听器

import { onMounted, onUnmounted } from'vue'

exportdefault {
  setup() {
    let stopWatch = null
    
    onMounted(() => {
      // 异步创建监听器
      setTimeout(() => {
        stopWatch = watch(/* ... */)
      }, 1000)
    })

    onUnmounted(() => {
      if (stopWatch) {
        stopWatch() // 必须手动清除
      }
    })
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.

关键点:Vue 无法追踪异步创建的监听器,需要开发者自行管理

2.2 动态条件监听

const searchKeyword = ref('')
let searchWatch = null

// 根据用户操作动态创建
function enableSearch() {
  searchWatch = watch(searchKeyword, () => {
    // 执行搜索逻辑
  })
}

function disableSearch() {
  searchWatch?.() // 主动销毁
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

典型场景:需要运行时动态启用的监听逻辑

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?.()
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

风险提示:全局监听器不会自动销毁,必须提供显式清理接口

三、智能管理方案

3.1 自动管理组合式函数

import { watchEffect, onScopeDispose } from'vue'

exportfunction useAutoCleanWatcher() {
const stop = watchEffect(() => {
    // 副作用逻辑
  })

// 自动注册清理
  onScopeDispose(() => {
    stop()
  })

return { stop }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

优势:利用 onScopeDispose 实现自动清理

3.2 监听器工厂模式

function createSmartWatcher(source, callback) {
const stop = watch(source, callback)

return {
    stop,
    restart: () => {
      stop()
      return createSmartWatcher(source, callback)
    }
  }
}

// 使用示例
const { stop } = createSmartWatcher(value, () => {})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.

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

责任编辑:武晓燕 来源: 前端之神
相关推荐

2024-09-05 08:50:11

2022-07-14 08:22:48

Computedvue3

2022-06-09 08:28:27

Vue3watchwatchEffec

2023-12-14 08:25:14

WatchVue.js监听数据

2021-12-01 08:11:44

Vue3 插件Vue应用

2021-11-30 08:19:43

Vue3 插件Vue应用

2023-11-28 09:03:59

Vue.jsJavaScript

2021-12-02 05:50:35

Vue3 插件Vue应用

2021-11-17 08:24:47

Vue3 插件Vue应用

2024-10-24 09:18:45

2020-09-19 21:15:26

Composition

2021-12-08 09:09:33

Vue 3 Computed Vue2

2020-11-12 08:32:14

Vue3模板优化

2023-11-16 08:29:26

2021-12-07 05:44:45

Vue 3 Watch WatchEffect

2022-06-21 12:09:18

Vue差异

2021-11-16 08:50:29

Vue3 插件Vue应用

2021-05-26 10:40:28

Vue3TypeScript前端

2022-03-10 11:04:04

Vue3Canvas前端

2020-12-01 08:34:31

Vue3组件实践
点赞
收藏

51CTO技术栈公众号