Reputation: 4725
Please see this minimum example
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);
},
},
});
As you can see, I have a component with an async function, it will be triggered after 300ms when you called it, by that time, the Vue component might be unmounted.
I think I can do this by storing a flag in the global via Lodash's uniqueID()
function to create a unique ID at mounted()
and beforeDestroyed()
.
Is there another easyier way to do that?
Upvotes: 7
Views: 6483
Reputation: 2067
I think that it would be best if you can control the timeout (using clearTimeout()
, for example, as suggested on the comments). In your case, as you're using a debounce
, depending on what lib you're using, you might not have that control.
In this case, one suggestion is to mix Node.contains
with vm.$el
. As follows:
export default {
methods: {
greet() {
const isUnmounted = !document.body.contains(this.$el)
}
}
}
Other alternative is to use destroyed
lifecycle to control this state internally.
I've provided a guiding example that might help you: https://codesandbox.io/s/smoosh-frost-fdisj.
Hope it helps!
Upvotes: 1
Reputation: 956
Here is what I just used and it worked great.
When you create the timeout, store the ID on this
. Then on beforeDestroy
, call clearTimeout
with the ID. Even if you manually cancel the timeout beforehand, clearTimeout
will not fail.
<script>
export default {
created() {
this.timeoutId = setTimeout(() => {}, 1000)
},
beforeDestroy() {
clearTimeout(this.timeoutId)
}
}
</script>
No need to set it in the data
property, as it isn't reactive.
Upvotes: 3
Reputation: 2355
You can use the beforeDestroy event like below :
mounted() {
this.$once("hook:beforeDestroy", () => {
//...
})
}
Upvotes: 0