需求
项目需求:添加tab标签页功能,切换tab时保留它们的状态,关闭标签清除状态。
解决:用 <KeepAlive>
内置组件将这些动态组件包装起来

使用
<KeepAlive>
默认会缓存内部的所有组件实例,但我们可以通过 include
和 exclude
prop 来定制组件。
由于项目所需要保存状态页面较少,我这里选择了include
。include
的值可以是以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组,这里便于后续动态删除使用数组。
!!!重点
include匹配的值是组件的name,如果发现使用include无效,八成是name不匹配。由于使用了setup语法糖,会自动生成组件name。
获取组件name:router.currentRoute.value.matched[0].components.default.__name

代码:
js
//App.vue
<template>
<div class="content" v-else>
<LeftVue />
<div class="rightVue">
<HeadVue />
<!--tab标签-->
<PageVue />
<!--main-->
<router-view v-slot="{ Component }">
<keep-alive :include="includeList">
<component class="main" :is="Component" :key="$route.fullPath" />
</keep-alive>
</router-view>
</div>
</template>
<script setup>
...
//包含缓存组件
const includeList = ref(["Index"]);
</script>
简单引入后,会发现组件名"Index"的页面会保存状态了。
动态删除缓存
思路:
1.在app.vue的includeList添加需要缓存组件名(如上)
2.当点击tab的关闭按钮时删除includeList中对应的值
3.从其他页面进入需要缓存的页面时,向includeList添加数据(防止需要缓存的页面,关闭后不会再缓存)
app.vue定义一个增删方法,tab标签点击关闭时调用方法(子组件调用父组件的方法)
js
//App.vue
<template>
<div class="content" v-else>
<LeftVue />
<div class="rightVue">
<HeadVue />
<!--tab标签-->
<PageVue @changeCaseKey="changeCaseKey" />
<!--main-->
<router-view v-slot="{ Component }">
<keep-alive :include="includeList">
<component class="main" :is="Component" :key="$route.fullPath" />
</keep-alive>
</router-view>
</div>
</template>
<script setup>
...
//省略无关代码
// 包含缓存组件
const includeList = ref(["Index"]);
// keepalive缓存------重点
const changeCaseKey = (path,fixed) => {
let val = path.default.__name;
let index = includeList.value.findIndex((item) => item == val);
if(fixed=='del'){
console.log(index);
index == -1 ? "" : includeList.value.splice(index, 1);
}else if(fixed=='add'){
index == -1 ? includeList.value.push(val):'';
}
};
</script>
js
//page.vue
<script setup>
...
//省略无关代码
// 接受父组件方法
const emits = defineEmits(["changeCaseKey"]);
//关闭tab
const delPage = (item, index) => {
emits("changeCaseKey",router.currentRoute.value.matched[0].components,'del');
};
</script>
js
//需要跳转增加的页面,使用
emits("changeCaseKey",router.currentRoute.value.matched[0].components,'add');
大功告成!!