react+anddesign组件Tabs实现后台管理系统自定义页签头
使用react和anddesign开发一个后台管理页签头。这里使用全局状态管理zustand来实现这个功能。
安装zustand
npm install zustand --save
创建store文件夹并在文件夹下创建useTabs.ts文件
// useTabs.ts
import { create } from 'zustand'interface tabLiSTState {tabList: Array<any>, // 页签头数据setTabList: (tabs: Array<any>) => void // 添加tabs全局方法
}export const useTabs = create<tabLiSTState>((set) => ({tabList: [{ title: "首页", path: '/' }],setTabList: (tabs) => set({ tabList: tabs }),
}))
创建Tabs组件组件
使用useEffect监听路由的变化,路由变化调用添加页签方法把当前菜单名称title和路径添加到全局状态管理中
import { useState, useEffect } from 'react'
import { Tabs } from 'antd'
import { useLocation, useNavigate } from 'react-router-dom'
import { routerArray } from '@/router/routes'
import MoreButton from './components/MoreButton'
import { useTabs } from '@/store/useTabs'
import './index.scss'
import { searchRoute } from '@/utils'
const LayoutTabs = () => {const { pathname } = useLocation()const navigate = useNavigate();const [activeTabs, setActiveTabs] = useState(pathname)const { tabList, setTabList } = useTabs()// 监听路由变化useEffect(() => {addTabs()// eslint-disable-next-line react-hooks/exhaustive-deps}, [pathname])const clickTabs = (path: string) => {navigate(path)}// 添加tabsconst addTabs = () => {const route = searchRoute(pathname, routerArray)const newTabList = JSON.parse(JSON.stringify(tabList))if(tabList.every(item => item.path !== pathname)) {newTabList.push({title: route.meta!.title,path: route.path,})}setTabList(newTabList)setActiveTabs(pathname)}// 关闭tabsconst closeTabs = (path) => {if(path === '/') returnif(pathname === path) {tabList.forEach((item, index) => {if(item.path !== path) returnconst nextTab = tabList[index + 1] || tabList[index - 1]if(!nextTab) returnnavigate(nextTab.path)}) }setTabList(tabList.filter(item => item.path !== path))}const item = tabList.map((i) =>{return {label: i.title,key: i.path,closable: i.path !== '/'}})return (<div className='tabs'><TabsanimatedhideAddtype="editable-card"activeKey={activeTabs}onChange={clickTabs}onEdit={closeTabs}items={item}/><MoreButton tabList={tabList} closeTabs={closeTabs} setTabList={setTabList} /></div>)
}
更多操作
主要是一些重新加载、关闭当前标签页、关闭左侧、关闭右侧、关闭其它、关闭所有
MoreButton组件
import { DownOutlined } from '@ant-design/icons';
import { useLocation, useNavigate } from 'react-router-dom'
import { Dropdown } from 'antd';const MoreButton = (props) => {const { pathname } = useLocation()const navigate = useNavigate();// 关闭左侧const closeLeftTabs = () => {const activeIndex = props.tabList.findIndex(item => item.path === pathname)const newTabs = props.tabList.filter((_, index) => index >= activeIndex || _.path === '/')props.setTabList(newTabs)}// 关闭右侧const closeRightTabs = () => {const activeIndex = props.tabList.findIndex(item => item.path === pathname)const newTabs = props.tabList.filter((_, index) => index <= activeIndex)props.setTabList(newTabs)}// 关闭其它const closeOtherTabs = () => {const list = props.tabList.filter(item => item.path === pathname || item.path === '/')props.setTabList(list)}// 关闭所有const closeAllTabs = () => {const list = props.tabList.filter(item => item.path === '/')props.setTabList(list)navigate('/')}const items = [{key: '1',label: '重新加载',onClick: () => {window.location.reload();}},{key: '2',label: '关闭当前',onClick: () => {return props.closeTabs(pathname)}},{key: '3',label: '关闭左侧',onClick: closeLeftTabs},{key: '4',label: '关闭右侧',onClick: closeRightTabs},{key: '5',label: '关闭其它',onClick: closeOtherTabs},{key: '6',label: '关闭所有',onClick: closeAllTabs},];return (<Dropdown.ButtonclassName='moreButton'icon={<DownOutlined />}menu={{ items }}type="primary">更多</Dropdown.Button>);
}export default MoreButton;