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,避免内存泄漏
对于复杂的监听逻辑,可以使用管理类统一管理
根据实际场景选择合适的取消方式