react antd tabs router 基础管理后台模版

在构建 React 后台管理系统时,使用标签页的方式展示路由是一种高效且用户友好的设计模式。这种实现方式通常允许用户在多个页面之间快速切换,并保留页面的状态,类似于浏览器的多标签页功能。

需求分析

1.动态标签页:根据用户的导航行为动态创建标签页。

2.标签页状态管理:需要管理哪些标签页已经打开,当前激活的标签页,以及关闭某些标签页的功能。

3.路由集成:每个标签页与 react-router-dom 的路由结合,切换标签页时也同步更新路由。

示例实现

以下是基于 React 和 react-router-dom 的后台管理系统,支持动态标签页和路由集成。

  1. 创建项目安装必要依赖
    确保安装了以下依赖:
bash 复制代码
npm create vite
npm install
npm install react-router-dom antd
  1. 完整代码实现
js 复制代码
import React, { useState } from 'react'
import { BrowserRouter as Router, Routes, Route, useNavigate, useLocation } from 'react-router-dom'
import { Tabs, Layout, Menu } from 'antd'

const { Header, Content } = Layout
const { TabPane } = Tabs

// 模拟的页面组件
const Dashboard = () => <div>仪表盘内容</div>
const UserList = () => <div>用户列表内容</div>
const Settings = () => <div>系统设置内容</div>

// 标签页的默认配置
const defaultTabs = [{ key: '/dashboard', label: '仪表盘', component: <Dashboard /> }]

const AppLayout = () => {
    const navigate = useNavigate()
    const location = useLocation()

    // 标签页状态
    const [tabs, setTabs] = useState(defaultTabs)
    const [activeTabKey, setActiveTabKey] = useState(defaultTabs[0].key)

    // 动态添加标签页
    const addTab = (key, label, component) => {
        if (!tabs.some(tab => tab.key === key)) {
            setTabs([...tabs, { key, label, component }])
        }
        setActiveTabKey(key)
        navigate(key)
    }

    // 关闭标签页
    const removeTab = targetKey => {
        const newTabs = tabs.filter(tab => tab.key !== targetKey)
        setTabs(newTabs)

        if (activeTabKey === targetKey) {
            const nextTab = newTabs[newTabs.length - 1]
            if (nextTab) {
                setActiveTabKey(nextTab.key)
                navigate(nextTab.key)
            } else {
                setActiveTabKey('/dashboard')
                navigate('/dashboard')
            }
        }
    }

    return (
        <Layout style={{ height: '100vh' }}>
            <Header>
                <Menu theme='dark' mode='horizontal' defaultSelectedKeys={['/dashboard']}>
                    <Menu.Item key='/dashboard' onClick={() => addTab('/dashboard', '仪表盘', <Dashboard />)}>
                        仪表盘
                    </Menu.Item>
                    <Menu.Item key='/users' onClick={() => addTab('/users', '用户列表', <UserList />)}>
                        用户列表
                    </Menu.Item>
                    <Menu.Item key='/settings' onClick={() => addTab('/settings', '系统设置', <Settings />)}>
                        系统设置
                    </Menu.Item>
                </Menu>
            </Header>
            <Content style={{ padding: '16px' }}>
                {/* 标签页 */}
                <Tabs
                    type='editable-card'
                    onChange={key => {
                        setActiveTabKey(key)
                        navigate(key)
                    }}
                    activeKey={activeTabKey}
                    onEdit={(targetKey, action) => {
                        if (action === 'remove') {
                            removeTab(targetKey)
                        }
                    }}
                >
                    {tabs.map(tab => (
                        <TabPane tab={tab.label} key={tab.key} closable={tab.key !== '/dashboard'}>
                            {tab.component}
                        </TabPane>
                    ))}
                </Tabs>

                {/* 路由 */}
                <Routes>
                    <Route path='/dashboard' element={<Dashboard />} />
                    <Route path='/users' element={<UserList />} />
                    <Route path='/settings' element={<Settings />} />
                </Routes>
            </Content>
        </Layout>
    )
}

const App = () => (
    <Router>
        <AppLayout />
    </Router>
)

export default App

功能点说明

1.动态标签页管理

复制代码
标签页通过 tabs 数组动态维护,新增时向数组添加对象,关闭时从数组中移除对象。
使用 TabPane 的 closable 属性控制是否允许关闭标签页。

2.同步路由和标签页

复制代码
点击菜单或切换标签页时,更新 activeTabKey 并通过 useNavigate 同步路由。
关闭标签页时,如果关闭的是当前激活的标签页,自动切换到最后一个标签页。

3.默认标签页

复制代码
默认标签页(如仪表盘)永远存在,且不可关闭。

4.路由内容展示

复制代码
Routes 定义了路由和对应的页面内容,标签页中渲染的组件会与路由匹配。

5.样式优化建议

复制代码
1.标签页溢出时滚动
Tabs 自带滚动支持,当标签页过多时可以左右滚动:
html 复制代码
<Tabs type="editable-card" size="small" tabBarGutter={4} />

2.页面布局优化

复制代码
添加侧边栏(Sider)用于更复杂的导航。
使用 Content 的内边距和背景色控制页面内容区域样式。

扩展功能

复制代码
持久化标签页
将标签页的状态保存到 localStorage,并在页面刷新时恢复。
js 复制代码
useEffect(() => {
  const savedTabs = JSON.parse(localStorage.getItem("tabs")) || defaultTabs;
  setTabs(savedTabs);
}, []);

useEffect(() => {
  localStorage.setItem("tabs", JSON.stringify(tabs));
}, [tabs]);

多级路由支持

复制代码
在标签页中加载嵌套路由。

权限管理

复制代码
根据用户权限动态控制可见的标签页和菜单。

通过以上实现,你可以轻松构建一个支持动态标签页、路由集成的后台管理系统,并扩展为更复杂的功能。

相关推荐
打野赵怀真1 分钟前
H5如何禁止动画闪屏?
前端·javascript
zhangxingchao1 分钟前
关于浮点数的思考
前端
Riesenzahn2 分钟前
你喜欢Sass还是Less?为什么?
前端·javascript
玄魂2 分钟前
基于Vue框架的开源大屏项目实践
前端·开源·数据可视化
晴殇i4 分钟前
一行代码解决跨域问题,JavaScript新特性解析
前端
挖稀泥的工人7 分钟前
面试看这一篇webpack
前端·webpack
卖报的小行家_9 分钟前
Vue3源码,拦截对象,对比Vue2
前端
蒜香拿铁12 分钟前
vue3自动导入组合式api
前端·javascript
日升13 分钟前
Chrome 134 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器
Mike_jia13 分钟前
一篇文章带你了解一款强大的本地镜像库系统---Harbor
前端