实现效果
点击左侧菜单显示标签并缓存
路由设置
在路由设置一个标识该页面是否缓存,这里设置一个keepalive
来标识是否缓存页面。注意name
不要重复
export default [
{
name: 'sys/index',
path: '/',
meta: { title: '首页', icon: '' ,keepalive : true},
components: {
//index为声明的router-view的name
index: () =>
import ('@/views/sys/index')
}
},
{
name: '404',
path: '/404',
meta: { title: '404', icon: '' },
components: {
//index为声明的router-view的name
index: () =>
import ('@/views/error/404')
}
},
]
菜单使用
使用方式如下:Component
相关是固定写法,使用keep-alive
包裹的会进行缓存,这里就是用到了设置的keepalive
的值进行判断,include
中是个数组,存放缓存的路由name
,比如打开一个页面就加一个该路由的name
。删除标签时调用removeTab
方法的时候删除keep-alive
缓存,否则就算是关掉标签还是会缓存页面的信息。
<router-view name="index" v-slot="{ Component }">
<keep-alive ref="keepAliveRef" :include="includeList">
<component :is="Component" :key="route.name" v-if="route.meta.keepalive" />
</keep-alive>
<component :is="Component" :key="route.name" v-if="!route.meta.keepalive" />
</router-view>
上面代码中route
的获取,获取的是vue-router
的useRoute
,打开菜单进行路由跳转时会触发监听器,然后将路由的name
存放到includeList
中,keep-alive
就会缓存该页面,下次打开后里面输入框等内容不变。
import { useRoute, useRouter} from "vue-router";
export default {
name: "index",
setup(props, content) {
const route = useRoute()
const keepAliveRef = ref()
let data = {
includeList : ref([]),//历史打开路由name
}
//监听
watch(() => route,(newVal,oldVal)=>{
if(newVal.meta.keepalive && data.includeList.value.indexOf(newVal.name) === -1){
data.includeList.value.push(newVal.name);
}
},{deep:true}) // 开启深度监听
let methods = {
/**
* @param targetName 路由对象
* */
removeTab(targetName, index) {
//清除缓存
const cachedInstances = keepAliveRef.value.cache;
for (const key in cachedInstances) {
const cachedInstance = cachedInstances[key].instance;
if (cachedInstance && cachedInstance.$options.name === targetName.name) {
cachedInstance.$destroy(); // 销毁指定组件实例,从而清除缓存
}
}
}
}
return {
route,
keepAliveRef,
...data,
...methods
}
}
}