Tag Archives: Vue router common problems

[Solved] Vue router common problems (push error, push duplicate route refresh)

Vue router FAQ

It is used to record Vue router bugs and common solutions encountered in work

Router.push reports an error, avoided redundant navigation to current location: “/xxx”

The main idea is that frequent route clicks lead to repeated routes. This error has no impact on the route jump function

Solution: override the push method

If you capture the exception, you will not report an error

let routerPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {
  return routerPush.call(this, location).catch(err => err)
}

Click the route repeatedly to refresh the page effect

When rewriting the vuerouter.prototype.push method, compare the fullpath attribute in the currentroute object of vuerouter with the parameters of the push function to judge whether it is the same route. If yes, use the following method to complete the page refresh

Method 1: window. Location. Reload()

The problem is that it will refresh the whole page, which is not recommended

let routerPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {

  let history = this.currentRoute && this.currentRoute.fullPath;
  if (location === history) {
    window.location.reload();
  }
  return routerPush.call(this, location).catch(err => err)
}

Method 2: V-IF controls router view to realize local refresh

More complex, but can achieve local refresh

Since this in VueRouter.prototype.push points to the VueRouter instance
The reference property "app" (this.app) of the "global Vue instance" (generated by main.js new Vue()) exists in that instance

So, the push function can manipulate the Vue instance inside.

Realize thinking:

  The vue instance uses provide to inject a getRouterAlive method, which returns the state variable isRouterAlive defined in the current vue instance.
    Then define a reloadChild method to change the state variable isRouterAlive to false, and then change it to true after the dom update

  Where a local refresh is needed, inject accepts the method getRouterAlive and binds it to the router-view
    v-if="Object.prototype.toString.call(getRouterAlive) == '[object Function]' && getRouterAlive()"

Implementation code:

main.js

// main.js

new Vue({
  router,
  store,
  render: h => h(App),
  provide() {
    return {
      getRouterAlive: this.getRouterAlive,
    }
  },
  data: {
    isRouterAlive: true
  },
  methods: {
    getRouterAlive() {
      return this.isRouterAlive;
    },
    reloadChild() {
      this.isRouterAlive = false;

      this.$nextTick(() => {
        this.isRouterAlive = true;
      })
    }
  }
}).$mount('#app')

router.js

// router/index.js
let routerPush = VueRouter.prototype.push;
VueRouter.prototype.push = function push(location) {

  let history = this.currentRoute && this.currentRoute.fullPath;
  if (location === history) {
    this.app.reloadChild && this.app.reloadChild();
  }
  return routerPush.call(this, location).catch(err => err)
}

Local refresh


...
<router-view v-if="Object.prototype.toString.call(getRouterAlive) == '[object Function]' && getRouterAlive()"></router-view>
...

inject: ["getRouterAlive"],
...