Vue Router 常見問題(push報錯、push重復路由刷新)


Vue Router 常見問題

用於記錄工作遇到的Vue Router bug及常用方案

router.push報錯,Avoided redundant navigation to current location: “/xxx”


大意為 路由頻繁點擊導致路由重復,該報錯對路由跳轉功能沒有任何影響

解決方案:重寫push方法

將異常捕獲就不會報錯了

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

重復點擊路由 刷新頁面效果

在重寫VueRouter.prototype.push方法時,利用VueRouter的currentRoute對象中的fullpath屬性與push函數的參數對比,判斷是否為同一路由。如果是,使用一下方法完成頁面刷新

方法一:window.location.reload()

問題在於會刷新整個頁面,不是很推薦

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

方法二:v-if 控制router-view實現局部刷新

較為復雜,但是能夠實現局部刷新

由於VueRouter.prototype.push中的this指向VueRouter實例
該實例中存在 "全局Vue實例"(main.js new Vue()生成的) 的引用屬性 "app"(this.app)

於是,push函數里面就可以操作Vue實例了。

實現思維:

  vue實例使用provide注入一個 getRouterAlive 方法,返回當前vue實例中定義的狀態變量 isRouterAlive
    再定義一個 reloadChild 方法,修改狀態變量 isRouterAlive的值為false,dom更新后再改為true

  需要局部刷新的地方 inject 接受 getRouterAlive 這個方法,再在router-view 上綁定
    v-if="Object.prototype.toString.call(getRouterAlive) == '[object Function]' && getRouterAlive()"

實現代碼:
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)
}

局部刷新

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

inject: ["getRouterAlive"],
...


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM