本文是機遇
提綱:
- 現有需求
- 各個解決方案的優缺點
- 相關的問題延伸
- keep-alive使用詳解
現有需求
每個項目中都存在許多列表數據展示頁面,而且通常包含一些篩選條件以及分頁。

並且,點擊表格中的某一列需要進行路由跳轉進入到詳情/添加/編輯頁面。
比較好的用戶體驗就是,從詳情/添加/編輯頁面返回之后希望列表頁保留上次離開時的篩選條件和頁碼。但是正常情況下路由跳轉之后實例已經被銷毀。
可選的解決方案
1.保留狀態數據:
利用state存儲狀態,如篩選的品牌,時間范圍,分頁。在路由跳轉到詳情/添加/編輯的時候存儲到state(vuex)中,如果跳轉到其它路由就重置。
缺點:每個列表的篩選條件有差別,還要在每個列表實例創建時讀取狀態(麻煩),但是也可以使用computed屬性返回狀態。
2.保留頁面,保留實例:
keep-alive,在路由跳轉時並沒有銷毀實例。
keep-alive
使用原理:
1.包裹動態組件時會緩存組件實例,而不是銷毀
2.keep-alive內路由切換時會調用activated和deactivated這兩個鈎子
使用方法:
- 套在router-view外面,受到影響的范圍就是router-view 里面的路由跳轉。

- vue 2.1.0版本新增include和exclude屬性以選擇性的緩存哪些組件(感覺使用范圍比較窄,有需要的自己看)
使用條件:
- vue.js 1.0

- vue.js 2.0

- 非函數式組件
什么是函數式組件?
render函數中創建模版內容(一般我們用不上,所以這個條件基本上沒影響)
使用需要注意問題:
1.要用在transition里面(具體原因不清楚)

2.一旦根路由組件外面用到keep-alive,里面的所有路由跳轉都會受到影響
- 針對需要保留狀態的列表頁,在activated鈎子里面執行想要更新的操作,比如更新列表數據:

場景需求:
mounted或者created鈎子里面獲取列表數據
路由離開之后跳轉回來,mounted或者created鈎子不會被調用,但是我需要更新數據。
解決方法:
1.定義firstIn屬性,初始化為true,表示是否第一次進入該路由。且在第一次執行activated鈎子的時候將該值置為false。
2.把mounted或者created鈎子中的數據初始化操作轉移到activated鈎子中。
- 針對不需要保留狀態的其它頁面,直接添加deactivated鈎子並銷毀實例就可以了。

3.發生菜單級別的跳轉是否需要重新渲染

注意每一個條件分支一定要執行next,否則實例被銷毀了頁面就不會被重新渲染。
其它問題:
1.非keep-alive包圍的路由組件的activated和deactivated鈎子是不會被觸發的。舉個例子:

假設路由跟節點有keep-alive包裹:
- AC兩個組件都可以被觸發activated和deactivated鈎子
- BD不會被觸發activated和deactivated鈎子,因為BD組件不是路由組件
- F也不會被觸發,即使F是路由組件,但是,如果keep-alive有包裹E組件中的router-view,則F也可以被觸發
總結一下
優點:
1.簡單粗暴
2.相比於計算屬性更脫離實際場景一些
缺點:
1.對於不需要緩存的路由都需要調用destroy 方法銷毀。