ChatGPT解决这个技术问题 Extra ChatGPT

Vuejs: Event on route change

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.


t
tony19

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


And use $route: function(to, from) { if you want to support older browsers, and aren't using babel.
but how can I react immediately to route params or query params if the component is getting instantiated / initialised at first? Would I do it in created() or mounted() or beforeRouteUpdate lifecycle hook or where?
Why would anyone not use Babel @PaulLeBeau?
This helped me: stackoverflow.com/questions/40404787/… <router-view :key="$route.fullPath"></router-view>
Excelent, i needed this to update my toolbar between sections
K
Kees de Kooter

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


A note: beforeRouteUpdate works only on the view that declares the method and not on any child component
The watch (1st code block) works also in Vue3
S
SoyChai

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

Don't forget to include in the import: import { Prop, Watch } from "vue-property-decorator";
I took me hours to finally realize that, any documentation out there?
Similar doc I can find: router.vuejs.org/api/#the-route-object Also instead of using the any type, you may want to use the interface Route from import { Route } from 'vue-router';
t
tony19

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.


M
Melardev

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.


downvoted because I get error this.$router.listen is not a function
@AngJobsonGithub Hi, from where are you calling this, this.$router will only be accessible on a Vue component, are you calling it from somewhere else? such as fetch()?
I think the call was inside a vue file, this.$router is available but not the listen function.
@AngJobsonGithub It has to be called from within a Vue component, "this" should be a Vue Component and the project should be using VueRouter
The code mentioned above seems does not work in Vue 2.6.11. The code need to change to the following this.$router.history.listen((newLocation) =>{console.log(newLocation);}) in order to make it work. Thanks for the answer.
R
Reza Mahmoodi

import { useRouter } from "vue-router";

const router = useRouter();

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


D
Delowar Hosain

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

Thanks! this is what I'm looking for. Route leave event for a specific component.
p
pedram

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