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]);

多级路由支持

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

权限管理

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

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

相关推荐
平头哥~3 小时前
Day 07 _ 那条 1px 的线,为什么在手机上忽粗忽细
前端·css·样式·学习资料
小江的记录本3 小时前
【CSS】CSS 动画:transition、animation、transform、CSS3 新特性(附《思维导图》)
前端·css·安全·spring·前端框架·css3·动画
circuitsosk3 小时前
任务规划器的三种范式对比:ReAct、Plan-and-Execute 与 Tree-of-Thought 在真实业务中的取舍
前端·javascript·python·react.js·llm·ai agent
hzxpaipai5 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
小磊哥er5 小时前
深入解构Claude Code - 第 12 篇 · 整体串起来
javascript·ai编程
小磊哥er5 小时前
深入解构Claude Code - 第 11 篇 · 工程上的讲究
javascript·ai编程
深念Y7 小时前
Lenovo XiaoXinAir 14 — 性能模式切换
前端·网络
计算机魔术师7 小时前
Meta突然杀进第一梯队:一个新模型,把AI推理成本打下来8倍
前端
IT_陈寒7 小时前
Redis缓存雪崩把我坑惨了,这次长记性了
前端·人工智能·后端