《CMS后台系统》项目实战 详细分解(五)

简介: 《CMS后台系统》项目实战 详细分解(五)

下拉菜单

引入用户头像

// 引入useState
import React, {useEffect,useState} from 'react'
// 引入默认头像图片
import defaultAvatar from '../assets/defaultAvatar.jpg'
// 使用useState
const [avatar,setAvatar] = useState(defaultAvatar)
// 插入图片
 <img src={avatar} className="avatar" alt='' />
复制代码


b1775815e7074d7088b909f0eb02ac38_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


添加默认用户名

// 使用useState
const [username,setUsername] = useState('游客')
<span>{username}</span>
复制代码


注意:添加key!

const menu = (
        <Menu>
          <Menu.Item key={1}>
            修改资料
          </Menu.Item>
          <Menu.Divider />
          <Menu.Item key ={2}>>
            退出登录
          </Menu.Item>
        </Menu>
      );
复制代码


  • 实现效果图

dfd50450616e433986fa3b09a351a6c1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


修改样式

在base.less 下书写样式

756274a7984f4c6fb99d02d73549fb8b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


.right {
        height: 40px;
        .avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
        }
        span {
            margin-left: 10px;
            margin-right: 10px;
        }
    }
复制代码


  • 实现效果图

ec8671d5396a44ae83c7d3cd218d263f_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


修改下拉菜单边距

  • 原样

4d9db82a5178425c95c2940bd1a0d112_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


在base.less中书写对应a标签的属性

.ant-dropdown-link{
            height: 60px;
            display: block;
            color: #333;
            &:hover{
                color: #1890ff;
            }
        }
复制代码


  • 实现效果图

7348e1a89a7c425696f6c65003f88177_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


  • 使用useEffect

在Application中会找到请求存储的数据。

3ec3085a9ece4157932de45ee00bc7d0_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


我们将使用这些数据替代默认的用户名和用户头像。

  • 用户名
// 模拟componentDidMount
  useEffect(()=>{
    let username1 = localStorage.getItem('username')
    if(username1){
      setUsername(username1)
    }
  },[])
复制代码


  • 实现效果图

166f13e3cc40446284f0898264f30e46_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


  • 用户头像
// 模拟componentDidMount
  useEffect(()=>{
    let username1 = localStorage.getItem('username')
    let avatar1 = localStorage.getItem('avatar')
    if(username1) {
      setUsername(username1)
    }
    if(avatar1) {
      setAvatar('http://47.93.114.103:6688/' + avatar1)
    }
  },[])
复制代码


注意:传入图片时,记得添加路径。

  • 实现效果图

c49fb65f310d4420a6ac5bee2ffa7de2_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


退出登录

不可以直接使用Link,进行跳转,因为在Application中数据依然存在。退出时必须清除数据。

import {Link, useNavigate} from 'react-router-dom'
const navigate = useNavigate()
// 退出登录
  const logout = () => {
    message.success('退出成功,即将返回登录页')
    localStorage.clear();   // 清除localStorage中的数据
    setTimeout(() => navigate('/login'), 1500)
}
<Link to="/login"  onClick={logout} >退出登录</Link>
复制代码


  • 实现效果

db95854b91bb42408a379b940eb2aea1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


侧边栏布局

  • 创建Aside组件

8a9f504df08d41198cd70c4bf492340f_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


  • 修改App组件

a4a519dce04e484f90cdee701ca765d3_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


const App = () => {
const {Sider, Content } = Layout;
    return (
        <Layout id='app'>
            <Header/>
        <Layout>
        <Aside />
          <Content>
          <div>
            <Outlet/>   
          </div>
          </Content>
        </Layout>
        <footer>Footer</footer>
      </Layout>
    );
}
export default App;
复制代码


  • 书写Aside组件

Menu

传送门

ant.design/components/…

Aside组件

import React from 'react'
import { Menu } from 'antd';
import { ReadOutlined, EditOutlined, DatabaseOutlined } from '@ant-design/icons';
export default function Aside() {
  const handleClick = e => {
    console.log('click',e)
  };
  return (
    <Menu
        onClick={handleClick}
        style={{ width: 180 }}
        mode="inline"
        theme="dark" // 黑色主题
    >
      <Menu.Item key="3">Option 3</Menu.Item>
      <Menu.Item key="4">Option 4</Menu.Item>
      </Menu>
  )
}
复制代码


App组件

import Aside from './components/Aside'
复制代码


import React from 'react';
import "./assets/base.less"
import { Outlet } from 'react-router-dom';
import { Layout } from 'antd';
import Header from './components/Header'
import Aside from './components/Aside'
const App = () => {
const {Content } = Layout;
    return (
        <Layout id='app'>
            <Header/>
        <Layout>
        <Aside />
          <Content>
          <div>
            <Outlet/>   
          </div>
          </Content>
        </Layout>
        <footer>Footer</footer>
      </Layout>
    );
}
export default App;
复制代码


  • 实现效果图

c0f468d878a04e6c8cab14546081d206_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


  • 为Aside设置类名
<Menu
        onClick={handleClick}
        style={{ width: 180 }}
        mode="inline"
        className='aside'
        theme="dark" // 黑色主题
    >
      <Menu.Item key="3">Option 3</Menu.Item>
      <Menu.Item key="4">Option 4</Menu.Item>
      </Menu>
复制代码


  • App组件内设置属性名
import React from 'react';
import "./assets/base.less"
import { Outlet } from 'react-router-dom';
import { Layout } from 'antd';
import Header from './components/Header'
import Aside from './components/Aside'
function App() {
    return (
        <Layout id='app'>
            <Header/>
        <div className='container'>
         <Aside />       
        <div className='container_box'>
            <div>
              <Outlet/>   
            </div>
        </div>
      </div>  
        <footer>Footer</footer>
      </Layout>
    );
}
export default App;
复制代码


  • base.less 书写属性
.container{
    display: flex;
    // justify-content: space-between;
    .aside{
        height: calc(100vh - 140px);
    }
    .container_box{
        flex: 1;
        box-sizing: border-box;
        padding: 20px;
        display: flex;
        flex-direction: column;
        .container_content{
            height: calc(100vh - 210px);
            overflow: hidden;
        }
    }
}
复制代码


-实现效果

5c88f13faa4245c38e3ef4181ee2a07c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


添加图标

<Menu.Item key="1"><ReadOutlined /> 查看文章列表</Menu.Item>
      <Menu.Item key="2"><EditOutlined /> 文章编辑</Menu.Item>
      <Menu.Item key="3"><DatabaseOutlined /> 修改资料</Menu.Item>
复制代码


在文字和图标紧凑在一起的时候,我们需要可以敲进一个空格来使得排版更加美观。


  • 实现效果图

bef0713a1ca4460ca42d6b116597f618_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png



目录
相关文章
|
6月前
|
监控 NoSQL Java
十八张图带你入门实时监控系统HertzBeat
我们经常讲:研发人员有两只眼睛,一只是监控平台,另一只是日志平台。在对性能和高可用讲究的场景里,监控平台的重要性再怎么强调也不过分。 这篇文章,我们聊聊开源实时监控告警系统 HertzBeat 赫兹跳动。
十八张图带你入门实时监控系统HertzBeat
|
6月前
|
架构师 Java
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
jvm性能调优实战 - 35电商APP后台系统如何对Full GC进行深度优化
98 0
|
数据库
【自然框架】CMS之数据库设计
    在园子里也混了三年多,随笔200多,一开始只是想把自己的经验写一下,后来呢弄出来了一个“自然框架”,主要精力就放在了介绍自然框架的思路上面了。随笔多了就发现一个问题:有点乱。虽然博客有分组,但是只支持一级分组,不支持n级的。
1593 0
|
3月前
|
监控 小程序 数据处理
揭秘支付宝小程序性能优化秘籍:从加载到运行,每一步都快人一步!
【8月更文挑战第27天】本文深入探讨了支付宝小程序性能优化的关键技术和策略,包括减少网络请求、利用CDN加速、代码按需加载、图片压缩、懒加载以及性能监控等多方面内容,并提供了实用的示例代码,帮助开发者显著提升小程序的加载速度与运行效率,创造更佳用户体验。
79 1
|
6月前
|
Prometheus 监控 Cloud Native
JVM工作原理与实战(三十三):监控GC过程的工具
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了jstat工具、VisualVM插件、Prometheus + Grafana、GC日志等内容。
229 0
|
6月前
|
Arthas Prometheus 监控
JVM工作原理与实战(二十九):监控内存泄漏的工具
JVM作为Java程序的运行环境,其负责解释和执行字节码,管理内存,确保安全,支持多线程和提供性能监控工具,以及确保程序的跨平台运行。本文主要介绍了解决内存溢出的步骤、Top命令、VisualVM、Arthas、Prometheus + Grafana等内容。
405 0
|
小程序 数据可视化 数据库
云开发(微信-小程序)笔记(十七)---- cms(内容管理)及案例
云开发(微信-小程序)笔记(十七)---- cms(内容管理)及案例
527 0
|
存储 Java 对象存储
JavaWeb第八章课后题 会话跟踪
JavaWeb第八章课后题 会话跟踪
137 0
《CMS后台系统》项目实战 详细分解(八)
《CMS后台系统》项目实战 详细分解(八)
116 0
《CMS后台系统》项目实战 详细分解(八)
|
资源调度 API 数据处理
《CMS后台系统》项目实战 详细分解(七)
《CMS后台系统》项目实战 详细分解(七)
115 0
《CMS后台系统》项目实战 详细分解(七)