在vue3/vue-router4下使用keep-alive
旧版的语法已经失效
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
新版官方推荐使用
<router-view>、<keep-alive> 和 <transition>
transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
官方推荐的方式是只有keep-alive模式,却没有不需要keep-alive的使用方法
错误示范
这样会造成所有页面都没有缓存,还不知道原因。
<router-view v-slot="{ Component }" v-if="$route.meta.keepAlive">
<keep-alive>
<component :is="Component" >
<p>缓存页面</p>
</component>
</keep-alive>
</router-view>
<router-view v-slot="{ Component }" v-if="!$route.meta.keepAlive">
<component :is="Component" >
<p>没有缓存的页面</p>
</component>
</router-view>
解决方案1
<router-view v-slot="{ Component }">
<keep-alive v-if="$route.meta.keepAlive">
<component :is="Component" >
<p>缓存页面</p>
</component>
</keep-alive>
<component :is="Component" v-if="!$route.meta.keepAlive">
<p>没有缓存的页面</p>
</component>
</router-view>
使用解决方案1,在某些情况会有问题
假设A、B页面是缓存,C页面是不需要缓存。A、B间跳转不会有问题,A、B跳转C页面再返回时候缓存会失效一次。总结就是非缓存和缓存页面跳转会造成缓存的页面失效,只有再跳转缓存的页面才恢复正常。
这样可能和我们所预期的效果会不太一致。
解决方案2
<template>
<router-view v-slot="{ Component }">
<keep-alive :include="includeList">
<component :is="Component"></component>
</keep-alive>
</router-view>
</template>
<script lang="ts">
//使用动态include解析
//app.vue文件
export default {
name: 'App',
data(){
return {
includeList : []
}
},
watch:{
$route(to:any) {
//监听路由变化,把配置路由中keepAlive为true的name添加到include动态数组中
const that:any = this;
if(to.meta.keepAlive && that.includeList.indexOf(to.name) === -1){
that.includeList.push(to.name);
}
}
}
}
</script>