Nuxt3页面级keepalive的Bug临时解决方案
发布于2023-10-17 15:42 阅读2550次 Nuxt3有关3.5.1版仍然存在的一个NuxtPage页面级keepalive的内部bug问题,导致keepalive无法正常工作,其内置三个参数 include,exclude,max只有max参数能得到支持。
```
<NuxtPage :keepalive="{max:5}"/>
```
只有此情况下可以正常工作,include和exclude均无法正常,是因为Nuxt3仍然以路由参数来控制,其路由为匿名模式,导致开发者无法像Vue3中自己建store列表来控制页面缓存。经多种尝试后找到一个不完美的临时解决方案,初步达到开发者自建useState列表来控制页面级缓存功能的实现。如果你正急需此功能可参考使用,因为每次将to.meta.keepalive设置为false,让其下次访问能再次重新加载时,会导致所有页面的meta.keepalive为false。简单说就是如果一个页面访问后会被记如缓存,如果因某种原因需要将这个页面从useState列表中删除后,再一次访问该页面,因无法在自建useState列表中找到该页,所以将该页设置为meta.keepalive=false,确实可以实现该页面的再次加载,但细心的你会发现,所以页面再次访问时都变成不缓存,都需要重新执行onMounted一次,再重新被写入缓存。(这是唯一不完美的地方,但因为项目急用该keepalive功能,所以就将就着了)以下是实现方法。
1.在composables文件下建立一个aliveList.ts,主要用于将已经访问的页面记录进列表,以便用此列表控制keepalive
```
const useKeepAlive=()=>useState('keepAlive',()=>{
if (process.server) {
return ['!'];
}else{
return ['!'];
}
});
export const useAliveList=(type:string='',key:string='')=>{
let aliveMax:number=20;//定义最大缓存页数量
let list:any=useKeepAlive();//获取现有keepalive列表
if(type=='add'&&key){
if(list.value.includes(key)){
list.value=list.value.filter((i:keyof string)=>i!=key);
list.value.unshift(key);
}else{
list.value.unshift(key);
if(list.value.length>aliveMax) list.value.length=aliveMax;
}
}else if(type=='del'&&key){
list.value=list.value.filter((i:keyof string)=>i!=key);
}else if(type=='non'){
list.value=['!'];
}else if(!type&&!key){
return list;
}
};
```
2.在middleware中建立即将访问的页面缓存判断,并将页面写入缓存列表。
```
export default defineNuxtRouteMiddleware((to,from)=>{
//keepalive缓存判断 系统BUG 临时解决方法 不完美 任意一次将to/from.meta.keepalive=false之后 全部变false
if(useAliveList().value.includes(to.name)){
to.meta.keepalive=true;
}else{
useAliveList('add',to.name?.toString());//添加到缓存列表
if(to.matched.length>0&&to.matched[0].meta.keepalive){
to.meta.keepalive=false;
}else{
to.meta.keepalive=true;
}
}
if(to.matched.length>0) to.matched[0].meta.keepalive=true;
});
```
3.如果因某此操作需要将其中一个页面清除缓存以便再次访问时加载最新数据
```
useAliveList('del','xxx-xxxx');//删除某页
useAliveList('add','xxx-xxxx);//添加某页
useAliveList('non');//清除全部缓存页
```