vue3 watch 中的清理负作用
时间: 2025-01-03 19:36:50 浏览: 13
### Vue3 中 `watch` 的清理副作用机制
在 Vue 3 中,`watch` 提供了一个强大的方式来响应数据变化并执行相应的逻辑。为了确保应用程序的高效运行,在某些情况下需要清理不再必要的副作用。这可以通过传递给回调函数的第三个参数中的 `immediate` 或者通过返回一个清除函数实现。
当定义带有清理需求的监视器时,可以在回调函数内部返回一个函数作为清理操作[^3]:
```javascript
import { ref, watch } from 'vue';
const source = ref(0);
let cleanupFunction;
// 定义具有清理功能的 watcher
watch(
() => source.value,
(newValue, oldValue, onInvalidate) => {
// 注册清理逻辑
onInvalidate(() => {
if (cleanupFunction) {
cleanupFunction();
}
});
// 模拟发起网络请求或其他异步操作
cleanupFunction = someAsyncOperation(newValue);
console.log(`Source changed to ${newValue} from ${oldValue}`);
},
{ immediate: true }
);
```
在这个例子中,每当被观察的数据发生变化时,都会先调用上一次注册的清理函数(如果有),然后再执行新的业务逻辑。这种模式特别适用于处理像定时器、事件监听器以及未完成的 AJAX 请求这样的场景,可以有效防止内存泄漏和其他潜在问题的发生[^2]。
对于更复杂的案例,比如取消尚未完成的 HTTP 调用,可以利用 Axios 库提供的 cancel token 功能配合 `onInvalidate` 来达到目的[^1]:
```javascript
import axios from 'axios';
import { ref, watchEffect } from 'vue';
function useFetch(url) {
const data = ref(null);
const error = ref(null);
let cancel;
watchEffect(async () => {
try {
// 取消之前的请求
if (cancel) cancel();
// 创建一个新的取消令牌
const CancelToken = axios.CancelToken;
cancel = function() {};
const response = await axios.get(url, {
cancelToken: new CancelToken(c => (cancel = c)),
});
data.value = response.data;
} catch (err) {
if (!axios.isCancel(err)) {
error.value = err.message || "An unknown error occurred.";
}
}
});
return { data, error };
}
```
上述代码展示了如何在一个组件卸载前安全地中止任何正在等待的结果,从而避免不必要的更新或错误报告[^5]。
阅读全文