Using tabs navigation in a backend project is an important feature

Here’s how to do this with the umi framework and the corresponding plug-in

Reference: the react – activation

Reference implementation: Implements a tabs

The architecture used in the project is UMI3 + REACT17 + ANTD PRO5

1. Introduce and use related plug-ins

Plugin address: umi-plugin-keep-alive

npm install umi-plugin-keep-alive --save
# or
yarn add umi-plugin-keep-alive

2. Common component encapsulation

Components folder to create a Keepavlietabs corresponding to the less style, please modify your own requirements

For KeepAlive and lifecycle usage solutions and questions, please go to the link react-activation above

Create the index.tsx file

// /components/KeepAvlieTabs/index.tsx import { useAliveController } from 'react-activation'; import { arrayDeduplicate } from '@/utils/Array'; import type { CachingNode } from './type'; import Tab from './Tab'; import styles from './index.less'; import { useHistory, useLocation } from 'umi'; Export Default Function KeepAliveTabs() {// History navigation const History = UseHistory (); // Location = UseLocation (); // getCachingNodes const {getCachingNodes} = UseAliveController (); const cachingNodes: CachingNode[] = getCachingNodes(); Let nodes: cachingNodes [] = arrayDeDuplicate (cachingNodes, 'path'); Filter ((item) => item.path! == '/home'); return ( <ul className={styles['alive-tabs']}> <li className={location.pathname === '/home' ? styles.home_active : styles.home_deactive} onClick={() => { history.push('/home'); }} > < div className = "tags - nav" > < span > home page < / span > < / div > < / li > {nodes. The map ((node) = > (< Tab key = {node! .id} node={node} /> ))} </ul> ); }

Create a tab.tsx file

// /components/KeepAvlieTabs/Tab.tsx import { useHistory, useLocation } from 'umi'; import { useAliveController } from 'react-activation'; import { CloseCircleOutlined } from '@ant-design/icons'; import type { CachingNode } from './type'; import styles from './index.less'; export default function Tab({ node }: { node: CachingNode }) { const history = useHistory(); const location = useLocation(); Const {getCachingNodes, DropScope} = UseAliveController (); const {getCachingNodes, DropScope} = DropScope (); const cachingNodes: CachingNode[] | any[] = getCachingNodes(); Function dropTab(e: React.MouseEvent<HTMLButtonElement>) {e.topPropagation (); // If you close the active KeepAlive Tab, Drop if (Location.PathName === Node. path) {// Routing asynchronous load control const Unlisten = history.listen(() => { setTimeout(() => { dropScope(node.name as string | RegExp); }, 30); }); unlisten(); // Go to the last TAB after the current node is removed if (cachingnodes.length <= 1) {history.push('/'); } else { const { path } = cachingNodes.filter((item) => item.path ! == node.path).pop(); history.push(path); } } else { dropScope(node.name as string | RegExp); }} // Set the current TAB style const className = () => {if (location.pathname === = node.path) {if (location.pathname === '/home') { return `${styles.active} ${styles.home_active}`; } return `${styles.active}`; } return `${styles.deactive}`; }; return ( <li className={className()} onClick={() => { history.push(node.path); }} > <div className="tags-nav"> <span>{node.name}</span> {<CloseCircleOutlined className={styles['close-btn']} onClick={dropTab} />} </div> </li> ); }

Create the type file type.ts

export type CachingNode = { createTime: number; updateTime: number; name? : string; id: string; [key: string]: any; };

Create style less files

.alive-tabs { height: 100%; margin: 0; padding: 0; overflow: hidden; white-space: nowrap; background: #fff; li { position: relative; display: inline-block; padding: 0 28px 0 10px; line-height: 32px; vertical-align: top; list-style: none; border-right: solid 1px #e6e6e6; cursor: pointer; The transition: 0.2 s background; } .active { height: 32px; Background: rgba (# 1890 ff, 0.1); border-bottom: 2px solid #1890ff; // background-color: #42b983; } .home_active { height: 32px; padding: 0 10px; Background: rgba (# 1890 ff, 0.1); border-bottom: 2px solid #1890ff; // background-color: #42b983; } .home_deactive { padding: 0 10px; } .deactive { background: #fff; } .close-btn { position: absolute; top: 11px; right: 10px; display: flex; align-items: center; justify-content: center; font-size: 12px; line-height: 0; outline: none; // transform: translateY(-50%); }}

3. Use KeepAlive in the component

Create Books/index. The TSX

import React from 'react'; import { KeepAlive, useActivate, useUnactivate } from 'react-activation'; Const Books: Reaction. FC = ()=>{useActivate(()=>{console.log(" I'm Activated "); }) useUnactivate(()=>{console.log(" I am cached "); }) return <div> </div>; }; export default (props: If (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => {if (any) => name={props.route.name} path={props.route.path} saveScrollPosition="screen"> <Books /> </KeepAlive> ); };

4. KeepAliveTabs mount to interface

Our page layout left upper and lower structure, in app. TSX, mount to our head, beyond the display scroll bar, specific style and function please add by yourself not to achieve the right mouse button menu to close all, switch left and right, please add by yourself, antd has related components

Export const layout: runtimeLayoutConfig = ({initialState}: any) => {return {// Control if the component is cacheable true, headerContentRender: () => <KeepAliveTabs />, ... }; };