【无标题】

 create-react-app my_eactapp
启动项目
npm start
下载路由插件
npm i react-router-dom@6.22.2```

项目基本框架

创建需要的路由文件,不管先后顺序,根据自己需求创建

我创建的是在srl下创建router文件夹编辑路由

在src下创建pages文件夹保存页面

src/router/indx.js

所以我就需要以下这几个页面

import { createBrowserRouter ,Navigate} from "react-router-dom"
import Main from '../pages/main'
import Home from "../pages/home"
import User from "../pages/user"
import Data from "../pages/data"
// import System from "../pages/system"
import System_info from "../pages/system/system_info"
const routes =[
    {
        path:'/',
        Component:Main,
        children:[
            // 重定向
            {
                path:'/',
                element:<Navigate to='home' replace></Navigate>
            },
            {
                path:'home',
                Component:Home
            },
            {
                path:'user',
                Component:User
            },
            {
                path:'data',
                Component:Data
            },
            {
                path:'system',
                // Component:System,
                children:[
                    {
                        path:"system_info",
                        Component:System_info
                    }
                ]
            }
        ]
    }
]

export default createBrowserRouter(routes)

src/pages/main.js(主入口)

import React from "react";
import { Outlet } from "react-router-dom";
const Main =()=>{
    return (
         <div>
             Main
             <Outlet></Outlet>
         </div>
     )
  
}
export default Main

src/pages/home/index.js

import React from "react";
const Home =()=>{
    return(
        <div>
            Home页面
        </div>
    )
}
export default Home

src/pages/data/index.js

import React from "react";
const Data=()=>{
    return(
        <div>
            Data 页面
        </div>
    )
}
export default Data

src/pages/user/index.js

import React from "react";
const User=()=>{
    return(
        <div>User页面</div>
    )
}
export default User

src/pages/system/system_info/index.js

import React from "react";
const System_info=()=>{
    return(
        <div>
            system_info 页面
        </div>
    )
}
export default System_info

配置app.js文件

APP.js

import './App.css';
import { RouterProvider } from 'react-router-dom';
import router from './router';
function App() {
  return (
   <div className='app'>
    <RouterProvider router={router}/>
   </div>
  );
}

export default App;

引入antdesigin

下载antdesigin

npm i antd
npm i @ant-design/icons

导入layout组件

src/pages/main.js(主入口)

import React ,{useState}from "react";
import { Outlet } from "react-router-dom";
// 引入antdesign
import {
    MenuFoldOutlined,
    MenuUnfoldOutlined,
    UploadOutlined,
    UserOutlined,
    VideoCameraOutlined,
  } from '@ant-design/icons';
  import { Button, Layout, Menu, theme } from 'antd';
  const { Header, Sider, Content } = Layout;
const Main =()=>{
    // return (
    //     <div>
    //         Main
    //         <Outlet></Outlet>
    //     </div>
    // )
    const [collapsed, setCollapsed] = useState(false);
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken();
  return (
    <Layout>
      <Sider trigger={null} collapsible collapsed={collapsed}>
        <div className="demo-logo-vertical" />
        <Menu
          theme="dark"
          mode="inline"
          defaultSelectedKeys={['1']}
          items={[
            {
              key: '1',
              icon: <UserOutlined />,
              label: 'nav 1',
            },
            {
              key: '2',
              icon: <VideoCameraOutlined />,
              label: 'nav 2',
            },
            {
              key: '3',
              icon: <UploadOutlined />,
              label: 'nav 3',
            },
          ]}
        />
      </Sider>
      <Layout>
        <Header
          style={{
            padding: 0,
            background: colorBgContainer,
          }}
        >
          <Button
            type="text"
            icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
            onClick={() => setCollapsed(!collapsed)}
            style={{
              fontSize: '16px',
              width: 64,
              height: 64,
            }}
          />
        </Header>
        <Content
          style={{
            margin: '24px 16px',
            padding: 24,
            minHeight: 280,
            background: colorBgContainer,
            borderRadius: borderRadiusLG,
          }}
        >
          Content
        </Content>
      </Layout>
    </Layout>
  );
}
export default Main

修改默认样式

index.css

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
	margin: 0;
	padding: 0;
	border: 0;
	font-size: 100%;
  font: inherit;
  vertical-align: baseline;
  box-sizing: border-box;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
	display: block;
}
body {
	line-height: 1;
}
ol, ul {
	list-style: none;
}
blockquote, q {
	quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
	content: '';
	content: none;
}
a, a:hover{
  color: inherit;
  text-decoration: none;
}
table {
	border-collapse: collapse;
	border-spacing: 0;
}
html, body {
  width: 100%;
  /* height: 100%; */
  background-color: #f5f5f5;
  font-family: 'PingFangSC-Light', 'PingFang SC', 'STHeitiSC-Light', 'Helvetica-Light', 'Arial', 'sans-serif';
}


.fl{
  float: left;
}
.fr{
  float: right;
	.button-group-item{
		padding-left: 3px;
	}
}

.clearfix{
  zoom:1;
  &:after{
    display:block;
    clear:both;
    content:"";
    visibility: hidden;
    height:0;
  }
}
.main-container {
  min-height: calc(100vh - 64px)
}
.main-container .app-name {
  background-color: #001529;
  text-align: center;
  color: #fff;
  line-height: 64px;
  font-weight: bold;
  font-size: 16px;
}

给组件内添加样式

src/page/main.js

import React ,{useState}from "react";
import { Outlet } from "react-router-dom";
// 引入antdesign
import {
    MenuFoldOutlined,
    MenuUnfoldOutlined,
    UploadOutlined,
    UserOutlined,
    VideoCameraOutlined,
  } from '@ant-design/icons';
  import { Button, Layout, Menu, theme } from 'antd';
  const { Header, Sider, Content } = Layout;
const Main =()=>{
    // return (
    //     <div>
    //         Main
    //         <Outlet></Outlet>
    //     </div>
    // )
    const [collapsed, setCollapsed] = useState(false);
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken();
  return (
    <Layout className="main-container">
      <Sider trigger={null} collapsible collapsed={collapsed}>
       <h3 className="app-name"> 通用后台管理</h3>
        <Menu
          theme="dark"
          mode="inline"
          defaultSelectedKeys={['1']}
          items={[
            {
              key: '1',
              icon: <UserOutlined />,
              label: 'nav 1',
            },
            {
              key: '2',
              icon: <VideoCameraOutlined />,
              label: 'nav 2',
            },
            {
              key: '3',
              icon: <UploadOutlined />,
              label: 'nav 3',
            },
          ]}
          style={{
            height:'100%'
          }}
        />
      </Sider>
      <Layout>
        <Header
          style={{
            padding: 0,
            background: colorBgContainer,
          }}
        >
          <Button
            type="text"
            icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
            onClick={() => setCollapsed(!collapsed)}
            style={{
              fontSize: '16px',
              width: 64,
              height: 64,
            }}
          />
        </Header>
        <Content
          style={{
            margin: '24px 16px',
            padding: 24,
            minHeight: 280,
            background: colorBgContainer,
            borderRadius: borderRadiusLG,
          }}
        >
          Content
        </Content>
      </Layout>
    </Layout>
  );
}
export default Main

main.js拆分组件

拆aside组件

 拆分main.js组件中的aside组件- 1 创建src/compontens/co
mpontentAside/index.js 将需要用到的Aside组件需要的代码以及包导入

将组件通信代码先去掉,因为组件之间的调用变化了,也就是

 icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
            onClick={() => setCollapsed(!collapsed)}

 的相关代码先去掉

rc/compontens/compontentAside/index.js
import React from "react";
import {

    UploadOutlined,
    UserOutlined,
    VideoCameraOutlined,
  } from '@ant-design/icons';
  import {  Layout, Menu } from 'antd';
  const { Sider } = Layout;

const ConmonAside=()=>{
    return(
        <Sider trigger={null} collapsible >
        <h3 className="app-name"> 通用后台管理</h3>
         <Menu
           theme="dark"
           mode="inline"
           defaultSelectedKeys={['1']}
           items={[
             {
               key: '1',
               icon: <UserOutlined />,
               label: 'nav 1',
             },
             {
               key: '2',
               icon: <VideoCameraOutlined />,
               label: 'nav 2',
             },
             {
               key: '3',
               icon: <UploadOutlined />,
               label: 'nav 3',
             },
           ]}
           style={{
             height:'100%'
           }}
         />
       </Sider>
    )
}
export default ConmonAside

2 - 然后将该aside组件导入在main,js中

src/pages/main.js
import React from "react";
import { Outlet } from "react-router-dom";
// 引入antdesign
// import {
//     MenuFoldOutlined,
//     MenuUnfoldOutlined,
//     UploadOutlined,
//     UserOutlined,
//     VideoCameraOutlined,
//   } from '@ant-design/icons';
  import { Button, Layout,  theme } from 'antd';
  import ConmonAside from "../compontents/componentAside";
  const { Header, Content } = Layout;
const Main =()=>{
  
  const {
    token: { colorBgContainer, borderRadiusLG },
  } = theme.useToken();
  return (
    <Layout className="main-container">
     <ConmonAside/>
      <Layout>
        <Header
          style={{
            padding: 0,
            background: colorBgContainer,
          }}
        >
          <Button
            type="text"
          
            style={{
              fontSize: '16px',
              width: 64,
              height: 64,
            }}
          />
        </Header>
        <Content
          style={{
            margin: '24px 16px',
            padding: 24,
            minHeight: 280,
            background: colorBgContainer,
            borderRadius: borderRadiusLG,
          }}
        >
          Content
        </Content>
      </Layout>
    </Layout>
  );
}
export default Main

3 -创建路由配置文件

src/config/index.js
export default  [
    {
        path: '/home',
        name: 'home',
        label: '首页',
        icon: 'HomeOutlined',
        url: '/home/index'
    },
    {
        path: '/mall',
        name: 'mall',
        label: '商品管理',
        icon: 'ShopOutlined',
        url: '/mall/index'
    },
    {
        path: '/user',
        name: 'user',
        label: '用户管理',
        icon: 'UserOutlined',
        url: '/user/index'
    },
    {
        path: '/other',
        label: '其他',
        icon: 'SettingOutlined',
        children: [
        {
            path: '/other/pageOne',
            name: 'page1',
            label: '页面1',
            icon: 'SettingOutlined'
        },
        {
            path: '/other/pageTwo',
            name: 'page2',
            label: '页面2',
            icon: 'SettingOutlined'
        }
        ]
    }
]

编辑asidey的index.js更改动态路由

rc/compontens/compontentAside/index.js

 

import React, { lazy } from "react";
import MenuConfig from '../../config'
import * as Icon from '@ant-design/icons'; //取别名
  import {  Layout, Menu } from 'antd';
  const { Sider } = Layout;
  //动态获取icon。将icon处理成react组件,因为antdesign是这样处理的
  const iconToElement = (name)=> React.createElement(Icon[name])
//处理菜单数据
const items = MenuConfig.map((icon)=>{
    //没有子菜单
    const child = {
        key:icon.path,
        icon:iconToElement(icon.icon),
        label:icon.label
    }
    //有子菜单
    if (icon.children){
        child.children = icon.children.map(item=>{
            return{
                key:item.path,
                label:item.label
            }
        })
    }
 return child
    
})



const ConmonAside=()=>{
    return(
        <Sider trigger={null} collapsible >
        <h3 className="app-name"> 通用后台管理</h3>
         <Menu
           theme="dark"
           mode="inline"
           defaultSelectedKeys={['1']}
           items={items}
           style={{
             height:'100%'
           }}
         />
       </Sider>
    )
}
export default ConmonAside

效果展示

拆header组件

1 - 将header组要的代码以及包移动到src/compontens/conpontentHeader/index.js中

1.1实现header图标和收缩菜单的位置的设置,点击都想有下拉菜单的功能
src/compontens/conpontentHeader/index.js
import React from "react";
import { Layout,Avatar,Button,Dropdown } from "antd";
import { MenuFoldOutlined } from "@ant-design/icons";
import './index.css'

const {Header} = Layout
const ConmonHeader=()=>{

    const logout=()=>{
        alert("退出登录")
    }
    const items=[
        {
            key:'1',
            label:(
                <a target="_blank" rel="noopenner noreferrer">个人中心</a>
            ),
        },
        {
            key:'1',
            label:(
                <a onClick={ ()=> logout} target="_blank" rel="noopenner noreferrer">退出</a>
            ),
        }
    ]
    return(
        <Header className="header-container">
        <Button 
        type="text"
        icon={<MenuFoldOutlined/>}
        style={{
            fontSize:'16px',
            width:64,
            height:32,
            backgroundColor:'#fff'
        }}/>
        <Dropdown 
        menu={{items}}
        >
             <Avatar size={36} src={ <img src={require("../../assets/images/user.png")}/>} />
        </Dropdown>

       
        </Header>
    )
}
export default ConmonHeader
src/compontens/conpontentHeader/index.css

/* 头像和收缩图标分布左右上线剧中 */
.header-container{
    display: flex;
    justify-content: space-between;
    align-items: center;
}

src/assets/images/下添加头像的图片

1.2点击收缩button实现菜单的展开和收缩(兄弟组件的通信)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值