Vuejs: Event on route change

vue.jsVuejs2Vue Router

vue.js Problem Overview


In my main page I have dropdowns that show v-show=show by clicking on link @click = "show=!show" and I want to set show=false when I change route. Advise me please how to realize this thing.

vue.js Solutions


Solution 1 - vue.js

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

Solution 2 - vue.js

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

Solution 3 - vue.js

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';

Solution 4 - vue.js

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.

Solution 5 - vue.js

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.

Solution 6 - vue.js

import { useRouter } from "vue-router";

const router = useRouter();

router.afterEach((to, from) => { });

Solution 7 - vue.js

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 {}

Solution 8 - vue.js

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:

Navigation Guards

> 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:

In-Component Guards

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionkiprisView Question on Stackoverflow
Solution 1 - vue.jsVamsi KrishnaView Answer on Stackoverflow
Solution 2 - vue.jsShubham NigamView Answer on Stackoverflow
Solution 3 - vue.jsATHERView Answer on Stackoverflow
Solution 4 - vue.jsNiño Angelo Orlanes LapuraView Answer on Stackoverflow
Solution 5 - vue.jsMelardevView Answer on Stackoverflow
Solution 6 - vue.jsReza MahmoodiView Answer on Stackoverflow
Solution 7 - vue.jsDelowar HosainView Answer on Stackoverflow
Solution 8 - vue.jspedramView Answer on Stackoverflow