場景
在研發中有一個場景,創建頁和編輯頁是同一個組件不同的path同一個router-view,通過query的參數來區分創建頁還是編輯頁,左邊還有個nav欄,創建頁和列表頁,列表頁點擊某一項直接切換到編輯頁。現在有個問題就是點擊nav欄時,組件不重新加載更新。
解決方案
- 給router-view添加key
- 代碼示例:
<router-view :key="$route.path"></router-view>
- 方案講解
vue本身都有組件複用的能力,該路由對應的組件在路由地址path發生了改變但同一個組件,會複用該組件,不會再重新創建該組件實例,所以對應的寫在生命週期鉤子函數中的異步請求代碼就不會執行,頁面也不會重新渲染。想辦法讓它聲明不是同一組件即可
eg:雖然改變了path,但是引用還是同一組件,所以不能單純看地址欄的變化。(只有這個猜測之說,後續再調查下) - 不同點(網上查閱):
-
不設置 router-view 的 key 屬性
由於 Vue 會複用相同組件, 即 /page/1 => /page/2 或者 /page?id=1 => /page?id=2 這類鏈接跳轉時, 將不在執行created, mounted之類的鉤子, 這時候你需要在路由組件中, 添加beforeRouteUpdate鉤子來執行相關方法拉去數據 -
設置 router-view 的 key 屬性值爲 \(route.path 從/page/1 => /page/2, 由於這兩個路由的\)route.path並不一樣, 所以組件被強制不復用, 相關鉤子加載順序爲:
beforeRouteUpdate => created => mounted從/page?id=1 => /page?id=2, 由於這兩個路由的$route.path一樣, 所以和沒設置 key 屬性一樣, 會複用組件, 相關鉤子加載順序爲:
beforeRouteUpdate -
設置 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
-
- 代碼示例:
- 通過watch監聽$route
- 代碼示例:
$route(to,from){ console.log('to', to); if(to.path == 'xxx') { // coding } console.log('from', from); },
- 方案講解
watch能監聽任何data的變化,也包括路由的變化。通過to/from的參數來實行相應的回調。
- 代碼示例:
拓展
- beforeRouteUpdate不生效
原因:在vue-router官方文檔中說到,只有/foo/:id這樣形式的才能生效,和我的需求不符。
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被複用時調用
// 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
// 可以訪問組件實例 `this`
}
- $route.path 當前路由的路徑
- $route.fullPath 完整的路徑