vue-router切換路由時同一組件不更新問題

場景

在研發中有一個場景,創建頁和編輯頁是同一個組件不同的path同一個router-view,通過query的參數來區分創建頁還是編輯頁,左邊還有個nav欄,創建頁和列表頁,列表頁點擊某一項直接切換到編輯頁。現在有個問題就是點擊nav欄時,組件不重新加載更新。

解決方案

  1. 給router-view添加key
    1. 代碼示例:
      <router-view :key="$route.path"></router-view>
      
    2. 方案講解
      vue本身都有組件複用的能力,該路由對應的組件在路由地址path發生了改變但同一個組件,會複用該組件,不會再重新創建該組件實例,所以對應的寫在生命週期鉤子函數中的異步請求代碼就不會執行,頁面也不會重新渲染。想辦法讓它聲明不是同一組件即可
      eg:雖然改變了path,但是引用還是同一組件,所以不能單純看地址欄的變化。(只有這個猜測之說,後續再調查下)
    3. 不同點(網上查閱):
      1. 不設置 router-view 的 key 屬性
        由於 Vue 會複用相同組件, 即 /page/1 => /page/2 或者 /page?id=1 => /page?id=2 這類鏈接跳轉時, 將不在執行created, mounted之類的鉤子, 這時候你需要在路由組件中, 添加beforeRouteUpdate鉤子來執行相關方法拉去數據

      2. 設置 router-view 的 key 屬性值爲 \(route.path 從/page/1 => /page/2, 由於這兩個路由的\)route.path並不一樣, 所以組件被強制不復用, 相關鉤子加載順序爲:
        beforeRouteUpdate => created => mounted

        從/page?id=1 => /page?id=2, 由於這兩個路由的$route.path一樣, 所以和沒設置 key 屬性一樣, 會複用組件, 相關鉤子加載順序爲:
        beforeRouteUpdate

      3. 設置 router-view 的 key 屬性值爲 \(route.fullPath 從/page/1 => /page/2, 由於這兩個路由的\)route.fullPath並不一樣, 所以組件被強制不復用, 相關鉤子加載順序爲:
        beforeRouteUpdate => created => mounted

        從/page?id=1 => /page?id=2, 由於這兩個路由的$route.fullPath並不一樣, 所以組件被強制不復用, 相關鉤子加載順序爲:
        beforeRouteUpdate => created => mounted

  2. 通過watch監聽$route
    1. 代碼示例:
      $route(to,from){
          console.log('to', to);
          if(to.path == 'xxx') {
              // coding
          }
          console.log('from', from);
      },
      
    2. 方案講解
      watch能監聽任何data的變化,也包括路由的變化。通過to/from的參數來實行相應的回調。

拓展

  1. beforeRouteUpdate不生效
    原因:在vue-router官方文檔中說到,只有/foo/:id這樣形式的才能生效,和我的需求不符。
beforeRouteUpdate (to, from, next) {
    // 在當前路由改變,但是該組件被複用時調用
    // 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
    // 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
    // 可以訪問組件實例 `this`
}
  1. $route.path 當前路由的路徑
  2. $route.fullPath 完整的路徑

參考資料

router-view的key屬性解決路由更新問題

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章