如何判断 Vue 组件是否被卸载以防止异步函数访问卸载组件的数据?



请看这个最小的例子

import Vue from 'vue';
Vue.extend({
data() {
return {
name: 'James',
};
},
methods: {
greet() {
setTimeout(() => {
const componentIsUnmounted = ???; // How do I tell if component is unmounted?
if (!componentIsUnmounted) {
console.log(this.name);
}
}, 300);
},
},
});

如您所见,我有一个带有异步功能的组件,当您调用它时,它会在 300ms 后触发,到那时,Vue 组件可能会被卸载。

我想我可以通过 Lodash 的uniqueID()函数在全局中存储一个标志来做到这一点,以在mounted()beforeDestroyed()处创建一个唯一的 ID。

有没有另一种更简单的方法可以做到这一点?

这是我刚刚使用的,效果很好。

创建超时时,请将 ID 存储在this上。然后在beforeDestroy,用 ID 呼叫clearTimeout。即使您事先手动取消超时,clearTimeout也不会失败。

<script>
export default {
created() {
this.timeoutId = setTimeout(() => {}, 1000)
},
beforeDestroy() {
clearTimeout(this.timeoutId)
}
}
</script>

无需在data属性中设置它,因为它不是反应性的。

我认为最好是可以控制超时(例如,按照评论中的建议使用clearTimeout()(。在您的情况下,当您使用debounce时,根据您使用的库,您可能没有该控制权。

在这种情况下,一个建议是将Node.containsvm.$el混合。如下:

export default {
methods: {
greet() {
const isUnmounted = !document.body.contains(this.$el)
}
}
}

另一种方法是使用生命周期destroyed内部控制此状态。


我提供了一个可能对你有帮助的指导性例子:https://codesandbox.io/s/smoosh-frost-fdisj。


希望对您有所帮助!

您可以使用 beforeDestroy 事件,如下所示:

mounted() {
this.$once("hook:beforeDestroy", () => {
//...
})
}

最新更新