On my main page I have dropdowns that show v-show=show
by clicking on the link @click = "show=!show"
and I want to set show=false
when I change the route. Please advise me on how to realize this thing.
Setup a watcher on the $route
in your component like this:
watch:{
$route (to, from){
this.show = false;
}
}
This observes for route changes and when changed ,sets show
to false
If you are using v2.2.0 then there is one more option available to detect changes in $routes.
To react to params changes in the same component, you can watch the $route object:
const User = {
template: '...',
watch: {
'$route' (to, from) {
// react to route changes...
}
}
}
Or, use the beforeRouteUpdate guard introduced in 2.2:
const User = {
template: '...',
beforeRouteUpdate (to, from, next) {
// react to route changes...
// don't forget to call next()
}
}
Reference: https://router.vuejs.org/en/essentials/dynamic-matching.html
beforeRouteUpdate
works only on the view that declares the method and not on any child component
Just in case anyone is looking for how to do it in Typescript, here is the solution:
@Watch('$route', { immediate: true, deep: true })
onUrlChange(newVal: Route) {
// Some action
}
And yes as mentioned by @Coops below, please do not forget to include :
import { Watch } from 'vue-property-decorator';
Edit: Alcalyn made a very good point of using Route type instead of using any:
import { Watch } from 'vue-property-decorator';
import { Route } from 'vue-router';
import { Prop, Watch } from "vue-property-decorator";
any
type, you may want to use the interface Route
from import { Route } from 'vue-router';
Watcher with the deep option didn't work for me.
Instead, I use updated() lifecycle hook which gets executed everytime the component's data changes. Just use it like you do with mounted().
mounted() {
/* to be executed when mounted */
},
updated() {
console.log(this.$route)
}
For your reference, visit the documentation.
UPDATE
As stated by @CHANist, router.listen
no longer works, I don't know from which version it stopped working, but the good news (as also stated by @CHANist) is we can use:
this.$router.history.listen((newLocation) => {console.log(newLocation);})
OLD Response
The above responses are the better, but just for completeness, when you are in a component you can access the history object inside the VueRouter with: this.$router.history. That means we can listen to changes with:
this.$router.listen((newLocation) => {console.log(newLocation);})
I think this is mainly useful when used along with this.$router.currentRoute.path You can check what I am talking about placing a debugger
instruction in your code and begin playing with the Chrome DevTools Console.
listen
function.
this.$router.history.listen((newLocation) =>{console.log(newLocation);})
in order to make it work. Thanks for the answer.
import { useRouter } from "vue-router";
const router = useRouter();
router.afterEach((to, from) => { });
Another solution for typescript user:
import Vue from "vue";
import Component from "vue-class-component";
@Component({
beforeRouteLeave(to, from, next) {
// incase if you want to access `this`
// const self = this as any;
next();
}
})
export default class ComponentName extends Vue {}
using Vue Router is an alternative way, use the beforeRouteLeave after methods in your component like this:
<template>
<button @click="ShowMethod">DisplayButton</button>
</template>
<script>
data() {
return { show: true };
},
methods: {
ShowMethod() {
this.show = false;
}
},
beforeRouteLeave(to, from, next) {
this.show = false;
next();
}
</script>
according to VueJs documentation, it's called Navigation Guards check the link below:
The leave guard is usually used to prevent the user from accidentally leaving the route with unsaved edits. The navigation can be canceled by calling
In-Component Guards:
beforeRouteEnter beforeRouteUpdate beforeRouteLeave
beforeRouteLeave(to, from, next) {
// called when the route that renders this component is about to
// be navigated away from.
// has access to `this` component instance.
}
look at the below link for more information:
Success story sharing
$route: function(to, from) {
if you want to support older browsers, and aren't using babel.