• 路由meta里面增加keepAlive属性

定义状态,定义缓存【状态管理器文件】

/**
 * 路由缓存模型
 */
interface RouterStoreModel{
    /**
     * 需要缓存的路由
     */
    keepAliveViews:Array<any>;
     /**
     * 不需要缓存的路由
     */
    noKeepAliveViews:Array<any>;
}
/**
 * 路由缓存
 */
export const RouterStore=defineStore({
    id:'RouterStore',
    state:():RouterStoreModel=>({
        keepAliveViews:[],
        noKeepAliveViews:[],
    })
})

将缓存数据存入RouterStore【路由管理文件】

// 记录需缓存的路由/组件
let keepAliveViews:Array<any>=[];
let notAliveViews:Array<any>=[];
router.getRoutes().forEach((routeItem) => {
    if (routeItem?.meta?.keepAlive) {
        // 组件name和路由name保持一致, 所以可以直接使用routeItem.name
        // 也可以在 meta 中添加属性 compName 来用,或其他方案
        keepAliveViews.push(routeItem.name);
    }else{
        notAliveViews.push(routeItem.name);
    }
});
let routerState=RouterStore(store);
routerState.keepAliveViews=keepAliveViews;
routerState.noKeepAliveViews=notAliveViews;

在路由视图页面定义数据【路由视图文件】

/**
 * 缓存响应式数据
 */
const alive = reactive({
  keepAliveViews:routerState.keepAliveViews,
  notAliveViews: routerState.noKeepAliveViews,
})
/**
 * 监听路由缓存变化,重新赋值给缓存响应式数据
 */
watch(()=>routerState.keepAliveViews,()=>{
  alive.keepAliveViews=routerState.keepAliveViews;
  alive.notAliveViews=routerState.noKeepAliveViews;
})

路由视图代码【路由视图页面】

<template>
  <router-view #default="{ Component }">
    <keep-alive :include="alive.keepAliveViews" :exclude="alive.notAliveViews">
      <component :is="Component"  :key="route.meta.name" />
    </keep-alive>
  </router-view>
</template>

定义修改路由缓存方法【路由表文件或者其他页面均可】

/**
 * 修改需要缓存的路由数据
 * @param alive 匹配的缓存key
 * @param deleteInfo 需要删除的元素
 * @param addInfo 需要增加的元素
 */
const changeAliveViews=(alive:string,deleteInfo?:Array<any>,addInfo?:Array<any>)=>{
    /**
     * 获取当前缓存路由数据
     */
    let info=routerState[alive];
    /**
     * 最终结果
     */
    let result;
    if(deleteInfo){
        result = info.filter(el => !deleteInfo.includes(el));
    }
     if(addInfo){
        result=[...new Set(result.concat(addInfo))]
     }
    routerState[alive]=result;
}

调用【路由表文件】

{
        path: '/userList',
        name: 'userList',
        component: () => import('@/views/building/userList.vue'),
        meta: {
            title: '楼层用户',
            keepAlive: true,
        },
        beforeEnter:()=>{
            changeAliveViews("keepAliveViews",["userDetail"],["userList"]);
        },
    },

缓存实现 A》B,B不缓存,B》A,A缓存

注意:pinia需要在路由挂载后使用,不然提示pinia没有安装
目前解决方法:pinia单独文件定义

import type { App } from 'vue';
import { createPinia } from 'pinia';
const store = createPinia();
export function setupStore(app: App<Element>) {
    app.use(store);
}
export { store };

main.ts引入

import { createApp } from 'vue';
import { setupStore } from './store';
const app = createApp(App);
// 安装pinia
setupStore(app);

路由文件使用pinia的时候

import { store } from "@/store/index";
let routerState=RouterStore(store);

暂时没发现问题

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐