襄阳市文章资讯

如何取消Vue Watch监听的方法示例

2026-05-06 14:18:02 浏览次数:0
详细信息

1. 使用返回的停止函数(Vue 3)

// Composition API
import { watch, ref } from 'vue'

const count = ref(0)

// watch返回一个停止函数
const stopWatch = watch(count, (newVal, oldVal) => {
  console.log('count变化:', oldVal, '->', newVal)
})

// 调用停止函数取消监听
stopWatch()

2. 组件卸载时自动取消(Vue 3)

// 在setup中使用,组件卸载时会自动停止
import { watch, ref, onUnmounted } from 'vue'

export default {
  setup() {
    const count = ref(0)

    const stopWatch = watch(count, (newVal) => {
      console.log('count:', newVal)
    })

    // 也可以手动在组件卸载时停止
    onUnmounted(() => {
      stopWatch()
    })

    return { count }
  }
}

3. 使用条件控制(Vue 2/3通用)

// 通过条件判断控制是否执行
const count = ref(0)
const isWatching = ref(true)

watch(
  count,
  (newVal) => {
    if (!isWatching.value) return
    console.log('count:', newVal)
  }
)

// 取消监听
isWatching.value = false

4. Options API中的watch(Vue 2)

// Vue 2 Options API
export default {
  data() {
    return {
      count: 0
    }
  },

  watch: {
    count(newVal, oldVal) {
      console.log('count变化:', oldVal, '->', newVal)
    }
  },

  // 无法直接取消,但可以通过条件控制
  watch: {
    count: {
      handler(newVal, oldVal) {
        if (!this.isWatching) return
        console.log('count变化:', oldVal, '->', newVal)
      },
      immediate: true
    }
  },

  data() {
    return {
      isWatching: true
    }
  },

  methods: {
    stopWatching() {
      this.isWatching = false
    },
    startWatching() {
      this.isWatching = true
    }
  }
}

5. 使用$watch返回的停止函数(Vue 2)

// Vue 2 Options API
export default {
  data() {
    return {
      count: 0
    }
  },

  mounted() {
    // $watch返回取消函数
    this.unwatchCount = this.$watch(
      'count',
      (newVal, oldVal) => {
        console.log('count变化:', oldVal, '->', newVal)
      }
    )
  },

  beforeDestroy() {
    // 取消监听
    if (this.unwatchCount) {
      this.unwatchCount()
    }
  },

  methods: {
    stopWatching() {
      this.unwatchCount()
    }
  }
}

6. 监听多个数据源

import { watch, ref } from 'vue'

const count = ref(0)
const name = ref('')

// 监听多个数据源
const stopWatch1 = watch(count, handler)
const stopWatch2 = watch(name, handler)

// 批量取消
function stopAllWatches() {
  stopWatch1()
  stopWatch2()
}

7. 实用的封装示例

// watchManager.js
import { watch, ref, onUnmounted } from 'vue'

export function useWatchManager() {
  const watchers = []

  const watchAndTrack = (source, callback, options) => {
    const stop = watch(source, callback, options)
    watchers.push(stop)
    return stop
  }

  const stopAll = () => {
    watchers.forEach(stop => stop())
    watchers.length = 0
  }

  onUnmounted(stopAll)

  return {
    watch: watchAndTrack,
    stopAll,
    watchers
  }
}

// 使用示例
export default {
  setup() {
    const { watch: customWatch, stopAll } = useWatchManager()
    const count = ref(0)
    const name = ref('')

    customWatch(count, (val) => console.log('count:', val))
    customWatch(name, (val) => console.log('name:', val))

    // 一键取消所有监听
    const cancelAll = () => {
      stopAll()
    }

    return { count, name, cancelAll }
  }
}

最佳实践建议:

推荐使用Composition API的返回函数方式,代码更清晰 在组件卸载时务必清理watch,避免内存泄漏 对于复杂的监听逻辑,可以使用管理类统一管理 根据实际场景选择合适的取消方式

相关推荐