>#### 本文基于 Vue2.0
- 不緩存:
進入的時候可以用`created`和`mounted`鉤子,離開的時候用`beforeDestory`和`destroyed`鉤子,`beforeDestory`可以訪問`this`,`destroyed`不可以訪問`this`。
- 緩存了組件:
緩存了組件之后,再次進入組件不會觸發`beforeCreate`、`created` 、`beforeMount`、 `mounted`,如果你想每次進入組件都做一些事情的話,你可以放在`activated`進入緩存組件的鉤子中。
同理:離開緩存組件的時候,`beforeDestroy`和`destroyed`并不會觸發,可以使用`deactivated`離開緩存組件的鉤子來代替。
### keep-alive 簡介
`keep-alive`是 Vue 內置的一個組件,可以使被包含的組件保留狀態,或避免重新渲染。
用法也很簡單:
```
<keep-alive>
<component>
<!-- 該組件將被緩存! -->
</component>
</keep-alive>
```
### props
- include - 字符串或正則表達,只有匹配的組件會被緩存
- exclude - 字符串或正則表達式,任何匹配的組件都不會被緩存
```
// 組件 a
export default {
name: 'a',
data () {
return {}
}
}
```
```
<keep-alive include="a">
<component>
<!-- name 為 a 的組件將被緩存! -->
</component>
</keep-alive>可以保留它的狀態或避免重新渲染
```
```
<keep-alive exclude="a">
<component>
<!-- 除了 name 為 a 的組件都將被緩存! -->
</component>
</keep-alive>可以保留它的狀態或避免重新渲染
```
### 遇見 vue-router
西湖雨好大,借把傘躲躲雨...
`router-view`也是一個組件,如果直接被包在`keep-alive`里面,所有路徑匹配到的視圖組件都會被緩存:
```
<keep-alive>
<router-view>
<!-- 所有路徑匹配到的視圖組件都會被緩存! -->
</router-view>
</keep-alive>
```
然而產品汪總是要改需求,攔都攔不住...
### 問題
如果只想 `router-view` 里面某個組件被緩存,怎么辦?
- 使用 include/exclude
- 增加 router.meta 屬性
### 使用 include/exclude
```
// 組件 a
export default {
name: 'a',
data () {
return {}
}
}
```
```
<keep-alive include="a">
<router-view>
<!-- 只有路徑匹配到的視圖 a 組件會被緩存! -->
</router-view>
</keep-alive>
```
`exclude`例子類似。
>#### 缺點:需要知道組件的 name,項目復雜的時候不是很好的選擇
### 增加 router.meta 屬性
```
// routes 配置
export default [
{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: true // 需要被緩存
}
}, {
path: '/:id',
name: 'edit',
component: Edit,
meta: {
keepAlive: false // 不需要被緩存
}
}
]
```
```
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 這里是會被緩存的視圖組件,比如 Home! -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 這里是不被緩存的視圖組件,比如 Edit! -->
</router-view>
```
>#### 優點:不需要例舉出需要被緩存組件名稱
### 【加鹽】使用 router.meta 拓展
假設這里有 3 個路由: A、B、C。
- 需求:
- 默認顯示 A
- B 跳到 A,A 不刷新
- C 跳到 A,A 刷新
- 實現方式
- 在 A 路由里面設置 meta 屬性:
```
{
path: '/',
name: 'A',
component: A,
meta: {
keepAlive: true // 需要被緩存
}
}
```
- 在 B 組件里面設置 beforeRouteLeave:
```
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設置下一個路由的 meta
to.meta.keepAlive = true; // 讓 A 緩存,即不刷新
next();
}
};
```
- 在 C 組件里面設置 beforeRouteLeave:
```
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 設置下一個路由的 meta
to.meta.keepAlive = false; // 讓 A 不緩存,即刷新
next();
}
};
```
這樣便能實現 B 回到 A,A 不刷新;而 C 回到 A 則刷新。
### 實現前進刷新,后退不刷新
感謝 [iceuncle](https://www.jianshu.com/u/beced864ad95) 分享的 [《vue實現前進刷新,后退不刷新》](https://juejin.im/post/5a69894a518825733b0f12f2)。
### 總結
路由大法不錯,不需要關心哪個頁面跳轉過來的,只要 `router.go(-1)` 就能回去,不需要額外參數。
然而在非單頁應用的時候,`keep-alive` 并不能有效的緩存了
### 參考
- [issues#811](https://github.com/vuejs/vue-router/issues/811)
- [vue#keep-alive](https://cn.vuejs.org/v2/api/#keep-alive)
- [vue2.0 keep-alive最佳實踐](https://segmentfault.com/a/1190000008123035)
- 前言
- 寫在前言
- 一些開發遇到的問題
- H5標簽中的屬性控制
- el-table的每個對象的屬性值
- el-form多個表單同時驗證必填項
- el-table 修改表頭
- el-input的多種驗證
- vue鍵盤回車事件
- blob導出
- table中selectable( 是否勾選)
- 手動更新視圖
- 日期選擇器,自定義可選范圍
- select 自定義搜索
- 監聽回車事件
- 表格初始化不可勾選
- el-input輸入限制
- table時間格式轉換
- table自適應高度
- JS問題記錄
- js字符數組轉換為數字數組
- js防抖和節流
- JS電腦是否有網判斷
- JS屬性記錄
- 遍歷方法(12個)
- 改變原數組(9個)
- 不改變原數組(8個)
- JS數組、字符串常用方法
- 遍歷對象
- Vue
- vue-router
- vue-router 如何在新窗口打開頁面
- vue-router 之 keep-alive緩存篇
- keep-alive項目案例
- 路由知識點歸納總結
- params、query傳參
- vue問題記錄
- vuejs npm chromedriver 報錯
- vuex
- vuex個人理解
- Vuex的簡單實例應用