react 后台管理系统 路由配置 左边菜单栏

创建项目
安装依赖包npm install sass sass-loader react-router-dom ant
清空无用文件
新建项目工程文件夹
react 后台管理系统 路由配置 左边菜单栏_第1张图片
在styles/reset.scss重置样式并在index.scss中引入

@import './assets/styles/reset.scss'

建页面
路由基本配置

import React from 'react'
import { HashRouter, Route, Routes } from 'react-router-dom'

//登录界面
import Login from "./views/login/Login"

export default function App() {
  return (
    <div>
      <HashRouter>
        <Routes>
          <Route path='/login' element={<Login/>}></Route>
        </Routes>
      </HashRouter>
    </div>
  )
}

配置路径别名@
安装:npm install -D @craco/craco
在项目根目录中创建 craco 的配置文件:craco.config.js,并添加如下代码:

const path = require('path')
module.exports = {
  // webpack 配置
  webpack: {
    // 配置别名
    alias: {
      // 约定:使用 @ 表示 src 文件所在路径
      '@': path.resolve(__dirname, 'src'),
    },
  },
}

在项目根目录中新建 jsconfig.json,并添加如下代码:

{
    "compilerOptions": {
      "baseUrl": "./",
      "paths": {
        "@/*": ["src/*"]
      }
    }
  }

package.json 修改启动命令

  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test",
    "eject": "react-scripts eject"
  },

路由懒加载和重定向

import React, { lazy, Suspense } from 'react'
import { HashRouter, Navigate, Route, Routes } from 'react-router-dom'


//登录界面
import Login from "@/views/login/Login"
//框架
// 路由懒加载,需要配合suspense使用,否则可能会报错
const Layout = lazy(() => import('@/views/layout/Layout'))

export default function App() {
  return (
    <div>
      <HashRouter>
        <Routes>
          {/* 重定向 */}
          <Route path='/' element={<Navigate to='/layout'></Navigate>}></Route>
          <Route path='/login' element={<Login />}></Route>
          <Route path='/layout' element={
            <Suspense fallback={<div>Loading...</div>}>
              <Layout />
            </Suspense>
          }></Route>
        </Routes>
      </HashRouter>
    </div>
  )
}

二级路由

{/* 一级路由 */}
          <Route path='/layout' element={
            <Suspense fallback={<div>Loading...</div>}>
              <Layout />
            </Suspense>
          }>
            {/* 二级路由 */}
            <Route path='order' element={
              <Suspense fallback={<div>Loading...</div>}>
                <OrderManage />
              </Suspense>
            }>
            </Route>
          </Route>

二级路由出口

//Layout.jsx
import React from 'react'
import { Outlet } from 'react-router-dom'

export default function Layout() {
  return (
    <div>
        <h1>框架</h1>
        {/* 二级路由出口 */}
        <Outlet/>
    </div>
  )
}

在router/index.jsx中路由表

import { lazy } from 'react'


//登录
const Login = lazy(() => import('@/views/login/Login'))
// 框架
const Layout = lazy(() => import('@/views/layout/Layout'))
//数据中心
const DataCenter = lazy(() => import('@/views/dataCenter/DataCenter'))
//客服中心
const OrderManage = lazy(() => import('@/views/callCenter/OrderManage'))
// 审核中心
const StoreAudit = lazy(() => import('@/views/auditCenter/StoreAudit'))
const IdentityAudit = lazy(() => import('@/views/auditCenter/IdentityAudit'))
//运营中心
const SubjectManage = lazy(() => import('@/views/operationCenter/SubjectManage'))
const ProjectManage = lazy(() => import('@/views/operationCenter/ProjectManage'))
//管理中心
const CompanyManage = lazy(() => import('@/views/manageCenter/CompanyManage'))
const DepartmentManage = lazy(() => import('@/views/manageCenter/DepartmentManage'))


//路由表
export default [
    //重定向
    {
        path:'/',
        redirect:'/data'
    },
    // 登录
    {
        path:'/login',
        element:<Login />
    },
    // 数据中心
    {
        path:'/data',
        element:<Layout/>,
        children:[
            {
                path:'',
                element:<DataCenter/>
            }
        ]
    },
    //客服中心
    {
        path:'/call',
        element:<Layout/>,
        children:[
            {
                path:'order',
                element:<OrderManage/>
            }
        ]
    },
    //审核中心
    {
        path:'/audit',
        element:<Layout/>,
        children:[
            {
                path:'store',
                element:<StoreAudit/>
            },
            {
                path:'identity',
                element:<IdentityAudit/>
            }
        ]
    },
    // 运营中心
    {
        path:'/operation',
        element:<Layout/>,
        children:[
            {
                path:'subject',
                element:<SubjectManage/>
            },
            {
                path:'project',
                element:<ProjectManage/>
            }
        ]
    },
    // 管理中心
    {
        path:'/manage',
        element:<Layout/>,
        children:[
            {
                path:'company',
                element:<CompanyManage/>
            },
            {
                path:'department',
                element:<DepartmentManage/>
            }
        ]
    }

]

工具函数中渲染动态路由函数

//utils/getRoute.jsx
import { Suspense } from "react"
import { Navigate, Route } from "react-router-dom"

export const getRoute = (routes) => {
    return routes.map(item => {
        return <Route path={item.path} key={item.path} element={item.redirect && !item.children ? <Navigate to={item.redirect} /> : <Suspense fallback={<div>Loading...</div>}>
            {item.element}
        </Suspense>}>
            {
                item.redirect && item.children ? <Route  path={item.path} element={<Navigate to={item.redirect} />} ></Route> : ""
            }
            {
                item.children && item.children.length ? getRoute(item.children) : ""
            }
        </Route>
    })
}

App.jsx中

import React from 'react'
import { HashRouter, Routes } from 'react-router-dom'
//引入路由表
import router from './router'
//导入工具函数 渲染路由
import { getRoute } from './utils/getRoute'

export default function App() {
  return (
    <div>
      <HashRouter>
        <Routes>
          {
            getRoute(router)
          }
        </Routes>
      </HashRouter>
    </div>
  )
}

安装ant design:npm install antd --save
Layout.jsx文件中布局

import React from 'react'
import { Outlet } from 'react-router-dom'
import "./Layout.scss"

import "./components/LeftMenu"
import LeftMenu from './components/LeftMenu'
export default function Layout() {
  return (
    <div className='layout-wrap'>
      <div className='left-menu'>
        <LeftMenu/>
      </div>
      <div className='right-cont'>
        <div className='right-top'>2</div>
        <div className='right-main'>
          {/* 二级路由出口 */}
          <Outlet />
        </div>
      </div>

    </div>
  )
}

//Layout.scss
.layout-wrap{
    display: flex;
    height: 100%;
    .left-menu{
        background-color: skyblue;
        // width: 200px;
    }
    .right-cont{
        flex: 1;
        display: flex;
        flex-direction: column;
        .right-top{
            height: 50px;
            background-color: pink;
        }
        .right-main{
            flex: 1;
            padding: 20px;
        }
    }
}

左边菜单栏完成LeftMenu.jsx中

import React, { useState } from 'react'
import { MailOutlined, SettingOutlined, AppstoreOutlined } from '@ant-design/icons';
import { Menu } from 'antd';
//导出路由跳转hooks函数
import { useNavigate } from 'react-router-dom';
function getItem(label, key, icon, children, type) {
    return {
        key,
        icon,
        children,
        label,
        type,
    };
}
const items = [
    getItem('数据中心', '/data', <SettingOutlined />),
    getItem('客服中心', '2', <MailOutlined />, [
        getItem('订单管理', '/call/order')
    ]),
    getItem('审核中心', '3', <AppstoreOutlined />, [
        getItem('商户审核', '/audit/store'),
        getItem('身份审核', '/audit/identity')
    ]),
    getItem('运营中心', '4', <SettingOutlined />, [
        getItem('专题管理', '/operation/subject'),
        getItem('项目管理', '/operation/project')
    ]),
    getItem('管理中心', '5', <SettingOutlined />, [
        getItem('公司管理', '/manage/company'),
        getItem('部门管理', '/manage/department')
    ]),
];

const rootSubmenuKeys = ['2', '3', '4', '5'];


export default function LeftMenu() {
    //展开的subMenu
    const [openKeys, setOpenKeys] = useState(['1']);
    //点击subMenu的回调函数
    const onOpenChange = (keys) => {
        const latestOpenKey = keys.find((key) => openKeys.indexOf(key) === -1);
        if (rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
            setOpenKeys(keys);
        } else {
            setOpenKeys(latestOpenKey ? [latestOpenKey] : []);
        }
    };
    //路由跳转的函数
    const navigate = useNavigate()
    //点击每一项
    const onClick = (e) => {
        console.log('click ', e);
        navigate(e.key)
    };
    return (
        <Menu
            onClick={onClick}
            style={{
                width: 256,
                background: 'skyblue'
            }}
            openKeys={openKeys}
            onOpenChange={onOpenChange}
            mode="inline"
            items={items}
        />
    )
}

你可能感兴趣的:(react.js,javascript,前端)