# vue中使用keepAlive组件缓存遇到的坑
**Repository Path**: lsx589/keepAlive
## Basic Information
- **Project Name**: vue中使用keepAlive组件缓存遇到的坑
- **Description**: vue中使用keepAlive组件缓存遇到的坑
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2019-09-23
- **Last Updated**: 2020-12-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# vue中使用keepAlive组件缓存遇到的坑
#### 介绍
vue中使用keepAlive组件缓存遇到的坑
#### 软件架构
vue+vue-router
#### 安装教程
[安装教程](https://cn.vuejs.org/v2/guide/installation.html)
#### 使用说明
项目开发中首页进入列表页再进入详情页需保存列表筛选状态,查阅了Vue官网后,发现vue提供了一个keep-alive组件
#### 项目配置
1. 在App.vue中的设置
`
`
2. 在router中增加配置meta
` { //列表
path: '/car/carList',
component: (resolve) => require(['../views/index/car/carList/carList.vue'], resolve),
name: 'carList',
meta: {
keepAlive:true
},
}, `
> 上面这个设置后发现问题了,从列表页进入detail页后,删选状态被保存了,返回的时候保存了删选状态下的列表,达到了预期效果
> 但问题在于但从详情返回到列表再返回到首页后,再由首页进入列表时依然显示是缓存中的页面,此刻页面没有刷新。
> 分析从index再次进入category时,直接读取了缓存的里的页面,头大。。。。。。。我的目标只是缓存从列表进入detail页面,其他的时候不缓存。
#### 解决方案
- 在列表页中启用beforeRouteLeave钩子函数
- beforeRouteLeave中只有从列表进入detail时才进行缓存,其他页面都将列表页的keepalive设置成false,并销毁此列表页组件;
```
beforeRouteLeave(to, from, next) {
if (to.fullPath == '/car/index') {
//清空删选信息
this.$store.commit('CARSTATUSTIME','0');
this.$store.commit('CARSTATUSTATION','不限');
this.$store.commit('CARSTATUSARRSTATION','不限')
};
if(to.name=='reserveDetail'){
if(!from.meta.keepAlive){
from.meta.keepAlive = true
}
}else{
from.meta.keepAlive = false
this.$destroy()
}
this.$loading.hide()
next()
},
```
**然后你会发现会出现一个问题**
- 第一次操作首页--> 列表---> 详情--->列表的时候是理想效果,但当第二次操作返回index后,进行首页--> 列表--> 详情--> 列表时,发现缓存的对象又不对了,从详情返回列表时,保存是的第一次进入详情的分类情况。
**解决方案**
- 根据vue-router提供的守卫可启用afterEach路由守卫,在afterEach中进行判断是否第一次进入,非第一次进入页面情况强制刷新一次列表页面。
> 我这里路由守卫写在main.js里
`
router.afterEach((to,from) =>{
if(to.name=='carList' && from.name == 'carIndex'){
let isRefresh = sessionStorage.getItem('isRefresh');
if(isRefresh == '0'){
sessionStorage.setItem('isRefresh',null);
window.location.reload();
console.log(1)
}else{
sessionStorage.setItem('isRefresh',0);
}
}else if(from.name == 'carList' && to.name == 'carIndex'){
sessionStorage.setItem('isRefresh',0);
}
})
`
**解决方案2**
- 在列表页中启用beforeRouteEnter钩子函数进行强制刷新。
`
beforeRouteEnter(to,from,next){
if(from.name == 'reserveDetail'){
window.location.reload();
}
next()
},
`
- 至此再操作一番,发现功能上已达到自己想要的结果
**但是同时会发现再进入列表页的时候页面会刷新两次**
#### 原因
在进入列表路由的时候,router.afterEach会第一时间判断是否是第一次进入该路由,进而判断是否 _强制刷新页面_ `window.location.reload();`然后再进入路由走该路由的生命周期
#### 解决方案
> 暂无()