废话不多说直接上代码:
vue组件:
<!-- keepAlive --><router-view v-slot="{ Component, route }"><keep-alive :include="shouldKeepAlive"><component :is="Component" :key="route.name" /></keep-alive></router-view>
分析:
使用的是include 匹配,这里我理解keep-alive不参与组件渲染,不能用v-if来显示隐藏,所以如果要动态渲染只能按照官网iniclude 或 Exclude,为什么这么理解呢?请看官网原话:
"<KeepAlive>
默认会缓存内部的所有组件实例,但我们可以通过 include
和 exclude
prop 来定制该行为。这两个 prop 的值都可以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组"
所以默认是会缓存内部所有组件实例,所以不能通过控制dom的方法来控制KeepAlive,也就不能用v-if/v-show这种方法,只能用官网提供的
include 和 exclude 关键属性来动态控制行为
这里我用的是
include,include 指的是包含导出的
组件名称
,千
万注意是组件名称不是路由组件名称,组件名称有两种方式:
第一种
是默认组件名称会以你起的文件名为默认组件名称如图:list,home,detail
第二种
是声明式组件名称:通过export default{name:"组件名称"}来声明;
无疑第二种的声明权重比第一种默认的要高
<script>
export default {name: "buy"
}
</script>
三.实现动态匹配缓存组件js如下:
1.通过rouer 的全局前置守卫来控制路由中的meta的参数
router.beforeEach((to, from, next) => {if ("keepAlive" in from.meta) {if (to?.name?.includes("detail")) {from.meta.keepAlive.value = true;} else {from.meta.keepAlive.value = false;}}if ("keepAlive" in to.meta) {if (from?.name?.includes("detail")) {to.meta.keepAlive.value = true;} else {to.meta.keepAlive.value = false;}}next();
});
2.通过判断keepAlive关键属性来动态匹配对应的缓存组件名:
这里用到了effect 所以注意路由meta对应的keepAlive 是响应式的
const route = useRoute();
const shouldKeepAlive = ref([])effect(() => {const result = router.options.routes.filter(route => {return route?.meta && route?.meta?.keepAlive?.value}).map(route => route.name);shouldKeepAlive.value = result;
})
写在最后:一点一滴记录代码生活,细微之处见成长 !