Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue.js router not calling beforeRouteUpdate (typescript)

I have a component that contains router-links to the same route, but with a different parameter. When navigating to those links, the url changes but the data isn't updating. I have beforeRouteUpdate defined, but it is never called.

import Vue from 'vue';
import { Component } from 'vue-property-decorator';
@Component
export default class AccountComponent extends Vue {
    address: string;
    account: Account;

    data() {
        return {
            account: null
        }
    }

    beforeRouteUpdate(to: any, from: any, next: any) {
        console.log('beforeRouteUpdate for ' + to.params.address);
        next();
    }

    mounted() {
        this.address = this.$route.params.address;
        this.loadData();
    }

    loadData() {
        console.log('Fetching data for ' + this.address);
        fetch('api/Account/Get?address=' + this.address)
            .then(response => response.json() as Promise<Account>)
            .then(data => {
                this.account = data;
            });
    }
}
like image 850
Erik Avatar asked Mar 12 '18 13:03

Erik


People also ask

What is new in vue-router?

vue-router introduces new hooks into the component. In this lesson we’ll show you how to use these new hooks in your class based Vue components in TypeScript.

How do I register a hook in vue router?

Additional Hooks If you use some Vue plugins like Vue Router, you may want class components to resolve hooks that they provide. In that case, Component.registerHooks allows you to register such hooks: import Component from 'vue-class-component' Component.registerHooks([ 'beforeRouteEnter', 'beforeRouteLeave', 'beforeRouteUpdate' ])

Is it possible to use generic type of VM in Vue?

I mistaken the type of vm. It should be the component activated, not the previous one. However, given this typing, I wonder if we can manage to give a good typing. Using generic isn't available here since V extends Vue won't accept specific type like Blog or so. In classical OOP, such use case is covered by F-bounded polymorphism.


2 Answers

Just ran into this issue myself 2 years after the question was asked but in addition to Simsteve7's answer I need to place that code inside it's own file

// router/componentHooks.ts

import Component from "vue-class-component";

// Register the router hooks with their names
Component.registerHooks([
    "beforeRouteEnter",
    "beforeRouteLeave",
    "beforeRouteUpdate"
]);

Then over in main.ts the very first line you import that in.

import './router/componentHooks' // <-- Needs to be first
import Vue from "vue";
import App from "./App.vue";
import router from "./router";

Before I just had the component's calls within mounted and was getting the slug through this.$route.params. Instead of that I put everything within mounted in it's own function and then called that from mounted using this.$route.params and beforeRouteUpdate's to.params. So for an example:

  async mounted() {
        await this.loadPage(this.$route.params.id)
  }

  async beforeRouteUpdate(to, from, next) {
        console.log(`beforeRouteUpdate ${to.params.id}`)
        await this.loadPage(to.params.id)
    next()
  }

  async loadPage(id) {
    //...
  }

Sources: https://class-component.vuejs.org/guide/additional-hooks.html

like image 139
rball Avatar answered Sep 20 '22 01:09

rball


Since there is still no answer, I'll post a possible issue.

Make sure to register the beforeRouteUpdate hook before initializing Vue.

Component.registerHooks([
    'beforeRouteEnter',
    'beforeRouteLeave',
    'beforeRouteUpdate',
]);

new Vue({...});
like image 38
Steve Maris Avatar answered Sep 23 '22 01:09

Steve Maris