Vue Apollo组合式API查询在组件卸载后仍触发更新怎么办?
我在用Vue3+Composition API+Vue Apollo时遇到了奇怪的问题,当组件被销毁后,之前用useQuery发起的查询结果还在触发更新。比如这个用户信息查询:
import { useQuery } from "@vue/apollo-composable";
import USER_QUERY from './user.gql';
export default {
setup() {
const { result } = useQuery(USER_QUERY);
onUnmounted(() => {
// 我以为这里清理就能停止监听
console.log('组件卸载了');
});
return { result };
}
}
但实际在控制台看到组件销毁后,当服务器有新数据推送过来,仍然会执行result.value的更新逻辑,导致已销毁组件的模板报错。试过在onUnmounted里手动调用result.stop()但提示stop方法不存在,应该怎么正确处理这种情况?
useQuery返回的不是result.stop(),它本身是响应式的,但清理工作得靠返回的onResult或者更关键的是——你得拿到query对象的stop()方法。正确的做法是在调用
useQuery的时候解构出stop函数,这个才是用来取消订阅的:useQuery返回的对象里有stop方法,专门用于停止监听和取消后续更新。你不调它,就算组件销毁了,GraphQL订阅还挂着,数据一回来就会尝试更新已经不存在的响应式引用,自然就报错了。CSS的话,这就像你开了个动画transition,元素都remove了DOM还拼命改样式,一样的道理。资源不用就得手动释放,别指望自动回收。
另外如果你用了
pollInterval或者subscribeToMore,记得这些也要在stop之后额外处理下,不过一般stop()会连带清掉。稳妥起见可以看看Vue Apollo文档里Subscription那块说明。