>#### 本文基于 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的简单实例应用