I have a simple question. I just want to cancel sub-component when route changed. Here is a sample. There is a home component which is the parent. And it has a subcomponent. I just want to stop interval function when route changes in the subcomponent mounted
import Home from "./components/Home.vue";
import Another from "./components/Another.vue";
const routes = [
{ path: '', component: Home },
{ path: '/another', component: Another }
];
const router = new VueRouter({
routes
});
const app = new Vue({
router
}).$mount('#app');
And this is home component. Home.vue
<template>
<sub-component></sub-component>
</template>
<script type="text/babel">
import SubComponent from "./components/Subcomponent.vue";
export default {
components:{
'sub-component':SubComponent
}
}
</script>
And this is subcomponent. Subcomponent.vue
<template>
<div> Sub component will run a interval </div>
</template>
<script type="text/babel">
import SubComponent from "./components/Subcomponent.vue";
export default {
components:{
'sub-component':SubComponent
},
mounted:function(){
setInterval(function(){
console.log("I should cancel when route changed");
},1000)
}
}
</script>
I tried beforeRouteLeave method but it stops only Home.vue methods.
Setting the history option to the result of the createWebHistory() function from vue-router switches the router from hash history mode to HTML5 history mode. This removes the hash from the URLs. There is no hash character before the index route path.
Vue Button component can be enabled/disabled by giving disabled property. To disable Vue Button component, the disabled property can be set as true .
We can enable the Vue Router's history mode to eliminate the hash from our app's URLs. However, we have to redirect our app to index. html since we don't want users to see errors when they go the URLs by entering it or refreshing the page. We can do this with any web server.
As you are using a sub-component (inside the route component), you will not be able to use beforeRouteLeave
directly.
Your sub-component is a child component of a route. Therefore you need to trigger the exit method of child component from your route component using Child Component Refs as explained in the guide page below:
https://vuejs.org/v2/guide/components.html#Child-Component-Refs
You can create a reference to your sub-component as follows:
<sub-component ref="mySubComponent"></sub-component>
And now in your route component, you can do the following:
beforeRouteLeave: function(to, from, next) {
// Indicate to the SubComponent that we are leaving the route
this.$refs.mySubComponent.prepareToExit();
// Make sure to always call the next function, otherwise the hook will never be resolved
// Ref: https://router.vuejs.org/en/advanced/navigation-guards.html
next();
}
Note: Your route component calls a method in the child sub-component called prepareToExit()
in this example, in which you can do the clean-up as follows:
methods: {
prepareToExit: function() {
console.log("Preparing to exit sub component, stopping 'twoSecondsTimerEvents'")
clearInterval(this.twoSecondsTimerEvents)
}
}
Here is a working example: https://jsfiddle.net/mani04/crwuxez3/ (all the details logged in console)
Please note: This example uses Vue 2.1.10 and Vue-Router 2.2.0 (latest versions as of today). There were some issues in the previous versions, around Navigation Guards functions, which are now fully resolved.
EDIT: Alternate method
After posting the above solution, I realized that there is a simpler way to do it. Your sub-component may not get route specific callbacks like beforeRouteLeave
, but it is still a Vue component that follows component lifecycle.
So, based on the component lifecycle diagram, you will have beforeDestroy
callback in the sub component that you can use to clear the timer.
Here is how you can do it:
const SubComponent = Vue.component('sub-component', {
template: `...`,
data: function() {...},
mounted: function() {...},
// 'prepareToExit' method not required here
// And also there is no need to handle 'beforeRouteLeave' in parent
beforeDestroy: function() {
console.log("Stopping the interval timer")
clearInterval(this.twoSecondsTimerEvents)
}
});
Advantages:
There are no disadvantages, but this trigger is not exactly tied to the route change, incase you wanted to do any other actions based on destination route. You may also use this if you like this better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With