react_后台管理_项目

目录

1.运行项目

2. 项目结构

①项目顶部导航栏

②项目左侧导航栏

③主页面-路由切换区


本项目使用的是 react+ts+scss 技术栈。

1.运行项目

在当前页面顶部下载本项目,解压后使用编辑器打开,然后再终端输入命令:

npm i

下载依赖后,运行项目:

npm run start

此时项目运行起来了,可以再浏览器看到运行效果:

2. 项目结构

在做自己的项目时,对于这个项目目录我们只需要更改以下几个文件:

src目录下的文件和App.tsx,可以根据自己项目需要进行更改。

①项目顶部导航栏

header.tsx:

import logo from '../../assets/images/logo.svg';
import './header.scss';

function Header() {
  return (
    <div className="headerAll">
      <header className="headerBox">
       <img src={logo} alt="logo" className='headerImg' />
       <div className="headerText">后台管理系统</div>
       <div className="circle">zh</div>
      </header>
      <header className="headerBoxPlaceholder">
      </header>
    </div>
  );
}

export default Header;

header.scss:

.headerBox {
  width: 100vw;
  height: 56px;
  background-color: #FFF;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9;
  min-width: 1140px;
  overflow: auto;

  .headerImg {
    width: 30px;
    height: 30px;
    position: absolute;
    top: 13px;
    left: 17px;
  }

  .headerText {
    font-size: 20px;
    position: absolute;
    top: 14px;
    left: 57px;
    font-weight: bold;
  }

  .navText {
    font-size: 16px;
    position: absolute;
    top: 16px;
    left: 218px;
  }

  .circle {
    width: 28px;
    height: 28px;
    line-height: 28px;
    border-radius: 50%;
    background-color: #19edcd;
    position: absolute;
    top: 14px;
    right: 14px;
    font-size: 12px;
    color: #FFF;
    text-align: center;
  }
}

.headerBoxPlaceholder {
  width: 100vw;
  height: 56px;
  box-shadow: 0px 4px 10px 0px rgba(78, 89, 105, 0.06);
}
②项目左侧导航栏

leftNavigation.tsx:

使用左侧导航图标使用svg,方便切换状态时换色,以及后期更改主题色。

import { ReactComponent as IconEducationGroup } from '../../assets/images/icon-education-group.svg';
import { ReactComponent as IconEduGroup } from '../../assets/images/icon-edu-group.svg';
import { ReactComponent as IconSet } from '../../assets/images/icon-set.svg';
import Arrow from "../../assets/images/icon-arrow.png";
import './leftNavigation.scss';
import { useState } from 'react';


function LeftNavigation() {
  // 左侧导航,一级按钮
  let navText = ['企业信息', '组织管理', '系统设置'];
  // 二级导航按钮,比如企业信息没有子级则二级导航为空数组
  let navTextChild = [[], ['组织架构', '部门设置'], ["日志设置", '通知设置']];
  // 当前选中的是哪个按钮,0是一级按钮,-1代表它没有子级选中的就是它本身
  const [currentBtn, setCurrentBtn] = useState([0, -1]);
  // 如果存在子层级,子层级展开还是合并,0合并,1展开
  const [childShow, setChildShow] = useState([1, 1, 1, 1]);

  /**
   * 判断按钮背景颜色
   * @param index 索引
   * @param flag 标志
   * @param indexChild 二级索引
   * @returns 返回className
   */
  function changeBGColor(index: number, flag: string, indexChild?: number): string {
    if (flag === 'one') {
      if (navTextChild[index].length === 0) {
        if (currentBtn[0] === index && navTextChild[index].length === 0) return 'first-order-tag bg-color'
      }
    } else {
      if (navTextChild[index].length !== 0 && currentBtn[0] === index && currentBtn[1] === indexChild) return 'first-order-tag bg-color'
    }
    return 'first-order-tag';
  }

  /**
   * 点击导航按钮进行页面切换
   * @param indexOne 一级索引
   * @param indexTwo 二级索引
   */
  function changeNavClick(indexOne: number, indexTwo?: number): void {
    if (navTextChild[indexOne].length === 0) { setCurrentBtn([indexOne, -1]) }
    if (indexTwo !== undefined && navTextChild[indexOne].length !== 0) {
      setCurrentBtn([indexOne, indexTwo])
    }

    if (indexTwo === undefined && navTextChild[indexOne].length !== 0) {
      updateItem(indexOne, childShow[indexOne] === 1 ? 0 : 1)
    }
  }

  /**
   * 只更新数组中的一个数值,数组[1]的值
   * @param indexFlag 一级索引
   * @param newValue 新的数值
   */
  function updateItem(indexFlag: number, newValue: number) {
    setChildShow(prevItems =>
      prevItems.map((item, index) => {
        if (index === indexFlag) {
          return newValue;
        }
        return item;
      })
    );
  }

  return (
    <div className="leftNavigationAll">
      <div className="leftNavigationBox">

        {navText.map((item, index) => (
          <div key={index}>
            {/* 第一层级 */}
            <div key={index} className={changeBGColor(index, 'one')} onClick={() => changeNavClick(index)}>
              <div className={currentBtn[0] === index ? 'navTextStyle-selected' : 'navTextStyle'}> {item}</div>
              {index === 0 && <IconEducationGroup className="icon-svg" stroke={currentBtn[0] === index ? '#00B498' : '#505553'} />}
              {index === 1 && <IconEduGroup className="icon-svg" stroke={currentBtn[0] === index ? '#00B498' : '#505553'} />}
              {index === 2 && <IconSet className="icon-svg" stroke={currentBtn[0] === index ? '#00B498' : '#505553'} fill={currentBtn[0] === index ? '#00B498' : '#505553'} />}
              {navTextChild[index].length !== 0 && <img alt="箭头" src={Arrow} className={childShow[index] === 1 ? 'arrow' : 'arrowHidden'}></img>}
            </div>

            {/* 第二层级 */}
            <div className={childShow[index] === 1 ? 'showDiv' : 'hiddenDiv'}>
              {navTextChild[index].length !== 0 && navTextChild[index].map((itemChild, indexChild) => (
                <div key={indexChild} className={changeBGColor(index, 'two', indexChild)} onClick={() => changeNavClick(index, indexChild)}>
                  <div className={(currentBtn[1] === indexChild && currentBtn[0] === index) ? 'navTextStyle-selected' : 'navTextStyle'}> {itemChild}</div>
                </div>
              ))}
            </div>
          </div>
        ))}

      </div>
    </div>
  );
}

export default LeftNavigation;

leftNavigation.scss:

.bg-color {
  background-color: #E8FAF8;
}

.showDiv {
  display: block;
}

.hiddenDiv {
  display: none;
}

.leftNavigationBox {
  z-index: 8;
  width: 200px;
  height: 100vh;
  min-height: 400px;
  background-color: #FFF;
  position: fixed;
  top: 0;
  left: 0;
  padding-top: 72px;
  padding-left: 8px;
  padding-right: 8px;
  box-sizing: border-box;

  .first-order-tag {
    width: 184px;
    height: 40px;
    // background-color: #E8FAF8;
    margin-bottom: 4px;
    border-radius: 6px;
    position: relative;
    cursor: pointer;

    &:hover {
      background-color: #F2F5F4;
    }

    .arrow {
      width: 12px;
      height: 12px;
      position: absolute;
      right: 16px;
      top: 14px;
      transform: rotateZ(180deg);
    }

    .arrowHidden {
      width: 12px;
      height: 12px;
      position: absolute;
      right: 16px;
      top: 14px;
      // transform: rotateZ(180deg);
    }

    .icon-svg {
      width: 18px;
      height: 18px;
      position: absolute;
      left: 12px;
      top: 11px;
    }

    .navTextStyle {
      font-size: 14px;
      color: #505553;
      position: absolute;
      left: 42px;
      top: 9px;
    }

    .navTextStyle-selected {
      font-size: 14px;
      color: #00B498;
      position: absolute;
      left: 42px;
      top: 9px;
    }
  }
}
③主页面-路由切换区

App.tsx:

所有路由写在这里,然后再左侧导航栏进行切换。

import './App.scss';
import Header from './pages/navigation/header';
import LeftNavigation from './pages/navigation/leftNavigation';
import Home from './pages/home';
import { Route, Routes } from 'react-router-dom'

function App() {
  return (
    <div className="App">
      <Header />
      <LeftNavigation />
      {/* 2. 使用路由组件,渲染路由,并且传入路由配置 */}
      <Routes>
        {/* comopnent替换为 element */}
        <Route path='/' element={<Home />}></Route>
      </Routes>

    </div>
  );
}

export default App;

home / index.tsx:

import './index.scss';
function Home() {
  return (
    <div className='homeBox'>
      <div className='homeBoxText'>应用主页</div>
    </div>
  );
}

export default Home;

以上就是项目的主要内容,可以将此项目当作基础框架进行二次开发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/778164.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue 数据大屏适配

1、准备俩个盒子 .dataScreen-content 盒子内容根据设计稿给的px单位进行正常的布局就行 2、盒子的CSS样式 .dataScreen-container {width: 100%;height: 100%;// 有背景图需要的样式background: url("./images/bg.png") no-repeat;background-repeat: no-repeat;b…

AI对于高考和IT行业的深远影响

目录 AI对IT行业的冲击及深远影响1. 工作自动化2. 新的就业机会3. 行业融合4. 技术升级和创新5. 数据的重要性 IT行业的冬天要持续多久&#xff1f;大学的软件开发类专业是否还值得报考&#xff1f;其他问题IT行业是否都是加班严重&#xff1f;35岁后就业困难是否普遍现象&…

在 PostgreSQL 中,如何处理多个长时间运行的查询对系统资源的竞争?

文章目录 一、问题分析二、解决方案&#xff08;一&#xff09;优化查询语句&#xff08;二&#xff09;限制资源使用&#xff08;三&#xff09;调整数据库参数&#xff08;四&#xff09;监控和分析查询性能&#xff08;五&#xff09;分区表&#xff08;六&#xff09;异步处…

策略为王股票软件源代码-----如何修改为自己软件73------------主界面右下角,大盘指数,时间显示 ,

IDS_MAINFRAME_SHINDEXTIP "沪:%2.f %+.2f %.2f亿" IDS_MAINFRAME_SZINDEXTIP "深:%2.f %+.2f %.2f亿" 主界面右下角,大盘指数,时间显示 , if( TIMER_TIME == nIDEvent ) { CSPTime time = CSPTime::GetCurrentTime(); …

ruoyi mybatis pagehelper 分页优化(自定义limit位置)clickhouse 外部数据源

例如加入clickhouse的分页时发现extends 不生效 则可以添加 startPage();registerDialectAlias("clickhouse", PageMySqlDialectPlus.class);List<MyMonitorlog> list monitorlogService.selectMonitorlogList(monitorlog);主要是需要注册 registerDialectAl…

ReAct Agent 分享回顾

在人工智能的迅速发展中&#xff0c;ReAct Agent作为一项前沿技术&#xff0c;受到越来越多的关注。本文结合ReAct Agent 提出者的访谈内容&#xff0c;探讨ReAct Agent的研究背景、技术挑战、未来展望&#xff0c;以及它与大模型的紧密联系&#xff0c;分析其科研成果与商业化…

kubernetes集群部署:关于CRI(一)

上周接到了一项紧急预研任务&#xff1a;kubernetes各项属性采集。目前我手里已经存在二进制部署的一套kubernetes&#xff08;v1.23版本CRI&#xff1a;dockershim&#xff09;集群&#xff1b;为了适配的广泛性&#xff0c;决定使用kuberadm工具部署最新&#xff08;v1.30版本…

三级_网络技术_04_中小型网络系统总体规划与设计

1.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 吞吐量是指路由器的路由表容量 背板能力决定了路由器的吞吐量 语音、视频业务对延时抖动要求较低 突发处理能力是以最小帧间隔值来衡量的 2.下列关于路由器技术特征的描述中&#xff0c;正确的是()。 路由器的…

【C语言】指针(1):入门理解篇

目录 一、内存和地址 1.1内存 1.2 深入理解计算机编址 二、指针变量和地址 2.1 取地址操作符&#xff08;&&#xff09; 2.2 指针变量和解应用操作符 2.2.1 指针变量 2.2.2 解引用操作符 2.3指针变量的大小 三、指针变量类型的意义 3.1 指针的解引用 3.1指针-整数…

贵州建筑三类人员安全员2024年考试最新题库练习题

一、单选题 1.建设工程安全管理的方针是&#xff08;&#xff09;。 A.安全第一&#xff0c;预防为主&#xff0c;综合治理 B.质量第一&#xff0c;兼顾安全 C.安全至上 D.安全责任重于泰山 答案&#xff1a;A 2.安全生产管理的根本目的是&#xff08;&#xff09;。 A.…

YOLOv8改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

207 课程表

题目 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [ai, bi] &#xff0c;表示如果要学习课程 ai 则 必须 先学习课程 bi 。 …

跨越语言的界限:Vue I18n 国际化指南

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 目录 国际化简介 vue-i18n 安装和配置 创建语言包 基本使用 切换语言 动态翻…

使用Python绘制堆积柱形图

使用Python绘制堆积柱形图 堆积柱形图效果代码 堆积柱形图 堆积柱形图&#xff08;Stacked Bar Chart&#xff09;是一种数据可视化图表&#xff0c;用于显示不同类别的数值在某一变量上的累积情况。每一个柱状条显示多个子类别的数值&#xff0c;子类别的数值在柱状条上堆积在…

电商视角如何理解动态IP与静态IP

在电子商务的蓬勃发展中&#xff0c;网络基础设施的稳定性和安全性是至关重要的。其中&#xff0c;IP地址作为网络设备间通信的基础&#xff0c;扮演着举足轻重的角色。从电商的视角出发&#xff0c;我们可以将动态IP和静态IP比作电商平台上不同类型的店铺安排&#xff0c;以此…

数据结构1:C++实现边长数组

数组作为线性表的一种&#xff0c;具有内存连续这一特点&#xff0c;可以通过下标访问元素&#xff0c;并且下标访问的时间复杂的是O(1)&#xff0c;在数组的末尾插入和删除元素的时间复杂度同样是O(1)&#xff0c;我们使用C实现一个简单的边长数组。 数据结构定义 class Arr…

C++(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例

C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例 文章目录 C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例1、概述2、实现效果3、主要代码4、源码地址 更多精彩内容&#x1f449;个人内容分类汇总 &#x1f448;&#x1f449;GIS开发 &#x1f448; 1、概述 支持多线程加…

系统安全与应用

目录 1. 系统账户清理 2. 密码安全性控制 2.1 密码复杂性 2.2 密码时限 3 命令历史查看限制 4. 终端自动注销 5. su权限以及sudo提权 5.1 su权限 5.2 sudo提权 6. 限制更改GRUB引导 7. 网络端口扫描 那天不知道为什么&#xff0c;心血来潮看了一下passwd配置文件&am…

在 PostgreSQL 中,如何处理大规模的文本数据以提高查询性能?

文章目录 一、引言二、理解 PostgreSQL 中的文本数据类型三、数据建模策略四、索引选择与优化五、查询优化技巧六、示例场景与性能对比七、分区表八、数据压缩九、定期维护十、总结 在 PostgreSQL 中处理大规模文本数据以提高查询性能 一、引言 在当今的数据驱动的世界中&…

Android 集成OpenCV

记录自己在学习使用OpenCV的过程 我使用的是4.10.0 版本 Android 集成OpenCV 步骤 下载OpenCV新建工程依赖OpenCV初始化及逻辑处理 1、下载OpenCV 并解压到自己的电脑 官网 地址&#xff1a;https://opencv.org/releases/ 个人地址&#xff1a;https://pan.baidu.com/s/19f…