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

多级路由支持

在标签页中加载嵌套路由。

权限管理

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

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

相关推荐
奇舞精选22 分钟前
在 Chrome 浏览器里获取用户真实硬件信息的方法
前端·chrome
热忱11281 小时前
elementUI Table组件实现表头吸顶效果
前端·vue.js·elementui
林涧泣2 小时前
【Uniapp-Vue3】setTabBar设置TabBar和下拉刷新API
前端
Rhys..2 小时前
Jenkins pipline怎么设置定时跑脚本
运维·前端·jenkins
易林示2 小时前
chrome小插件:长图片等分切割
前端·chrome
w(゚Д゚)w吓洗宝宝了2 小时前
单例模式 - 单例模式的实现与应用
开发语言·javascript·单例模式
zhaocarbon2 小时前
VUE elTree 无子级 隐藏展开图标
前端·javascript·vue.js
浏览器爱好者3 小时前
如何在AWS上部署一个Web应用?
前端·云计算·aws
xiao-xiang3 小时前
jenkins-通过api获取所有job及最新build信息
前端·servlet·jenkins
C语言魔术师3 小时前
【小游戏篇】三子棋游戏
前端·算法·游戏