ant-design-pro项目路由组件缓存keep-alive
如图,要实现的功能,将已点击过的菜单展示在顶部的tabs中,切换tab内容缓存.删除tab后清除页面缓存,点击菜单再打开是新页面
实现:
使用的是react-activation,其中有umijs的实现demo
官网地址https://www.npmjs.com/package/react-activation
1. 安装 yarn add umi-plugin-keep-alive
2. 在页面的通用组件里,一般是包裹所有页面组件的layout中添加
主要看标红的部分,其他是tabs的实现
commonLayout.tsx
import React, { useEffect, useState } from 'react'; import { PageContainer } from '@ant-design/pro-layout'; import { history, useModel } from 'umi'; import { find } from 'lodash'; import type { menuTabProps } from '@/services/types'; import { handleMenusToFlat } from '@/utils/base'; import { KeepAlive, useAliveController } from 'react-activation'; const CommonLayout: React.FC = (props: any) => { const { location, route } = props; const { pathname } = location; const [activeKey, setActiveKey] = useState<string>(''); const { dropScope } = useAliveController(); const { exitMenus, updateMenus } = useModel('exitMenus', (model) => ({ exitMenus: model.exitMenus, updateMenus: model.updateMenus, })); const flatMenus = handleMenusToFlat(route.routes); const noCachRoutes = ['/', '/user/login']; // 不需要缓存的路由 useEffect(() => { // console.log(333, location, flatMenus); if (noCachRoutes.includes(pathname)) return; const arr: menuTabProps[] = exitMenus.filter((item: menuTabProps) => item.key !== pathname); if (arr.length === exitMenus.length) { const activeTab = find(flatMenus, (item) => item.pathname === pathname) || {}; const activeMenu: menuTabProps = { tab: activeTab.name, key: pathname, closable: exitMenus.length > 0, // 新增时,第一个页面不能删除 }; arr.push(activeMenu); updateMenus(arr); } else if (exitMenus.length === 1) { // 删除时,只剩一个标签去掉删除图标 const data = exitMenus; data[0].closable = false; updateMenus(data); } setActiveKey(pathname); }, [location]); const onTabChange = (key: string) => { history.push(key); setActiveKey(key); // console.log(key); }; return ( <PageContainer tabList={exitMenus} onTabChange={onTabChange} header={{ title: null, }} tabProps={{ type: 'editable-card', hideAdd: true, activeKey, tabBarStyle: { paddingBottom: '3px', }, onEdit: (path: string) => { // console.log(path, exitMenus, pathname); let activePath = pathname; const arr: menuTabProps[] = exitMenus.filter((item: menuTabProps, i: number) => { if (item.key === path) { // 获取前一个标签 activePath = exitMenus[i - 1].key; } return item.key !== path; }); // 如果关闭当前标签,展示前一个标签 if (path === pathname) { history.push(activePath); } // 关闭页签去掉缓存 dropScope(path); updateMenus(arr); }, }} > <KeepAlive when={true} //组件卸载后缓存(离开页面时缓存)可以传入Boolean,array,function id={pathname} // 缓存多个页面时要有id name={pathname} // 页面的path地址 saveScrollPosition="screen" // 可以记住页面的滚动位置,切换页面是回到上一次滚动的位置,可以设置为false > {props.children} </KeepAlive> </PageContainer> ); }; export default CommonLayout;
这样就实现路由的缓存了,其他地方不需要改动