基于react18+arco+zustand通用后台管理系统React18Admin

React-Arco-Admin轻量级后台管理系统解决方案

基于vite4构建react18后台项目ReactAdmin。使用了react+arco-design+zustand+bizcharts等技术架构非凡后台管理框架。支持 dark/light主题、i18n国际化、动态路由鉴权、3种经典布局、tabs路由标签 等功能。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

技术框架

  • 编辑器:Vscode
  • 使用技术:react18+vite4+react-router+zustand+axios
  • 组件库:arco-design (字节前端react组件库)
  • 路由管理:react-router-dom^6.16.0
  • 状态管理:zustand^4.4.1
  • 模拟数据:mockjs^1.1.0 + axios^1.5.1
  • 图表库:bizcharts^4.1.22
  • 编辑器组件:@wangeditor/editor-for-react^1.0.6
  • markdown组件:@uiw/react-md-editor^3.23.6
  • 请求进度插件:nprogress^0.2.0

在这里插入图片描述
在这里插入图片描述

特点

  • 基于vite4.x搭建react18后台系统
  • 使用最新前端技术栈react18、zustand、bizcharts、react-router
  • 搭配字节react组件库arco.design
  • 支持中英文/繁体国际化
  • 支持动态路由权限验证
  • 支持动态tabs标签栏菜单
  • 内置多种通用模板布局

在这里插入图片描述
在这里插入图片描述

项目结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

App.jsx模板

引入语言包,配置权限路由。

/*** 入口模板* @author Hs
*/import { useEffect, useMemo } from 'react'
import { HashRouter } from 'react-router-dom'
// 通过 ConfigProvider 组件实现国际化
import { ConfigProvider } from '@arco-design/web-react'
// 引入语言包
import enUS from '@arco-design/web-react/es/locale/en-US'
import zhCN from '@arco-design/web-react/es/locale/zh-CN'
import zhTW from '@arco-design/web-react/es/locale/zh-TW'import { AuthRouter } from '@/hooks/useRoutes'
import { appStore } from '@/store/app'// 引入路由配置
import Router from './routers'function App() {const { lang, config: { mode, theme }, setMode, setTheme } = appStore()const locale = useMemo(() => {switch(lang) {case 'en':return enUScase 'zh-CN':return zhCNcase 'zh-TW':return zhTWdefault:return zhCN}}, [lang])useEffect(() => {setMode(mode)setTheme(theme)}, [])return (<ConfigProvider locale={locale}><HashRouter><AuthRouter><Router /></AuthRouter></HashRouter></ConfigProvider>)
}export default App

react-admin通用布局模板

在这里插入图片描述

支持分栏+垂直+水平布局样式。

在这里插入图片描述

/*** 主布局模板* @author Hs Q:282310962
*/import { useMemo } from 'react'
import { appStore } from '@/store/app'import Columns from './template/columns'
import Vertical from './template/vertical'
import Transverse from './template/transverse'function Layout() {const { config: { skin, layout } } = appStore()// 布局模板const LayoutComponent = useMemo(() => {switch(layout) {case 'columns':return Columnscase 'vertical':return Verticalcase 'transverse':return Transversedefault:return Columns}}, [layout])return (<div className="radmin__container"><LayoutComponent /></div>)
}export default Layout

react-router-dom路由管理

在这里插入图片描述

/*** @title    react-router-dom v6路由配置管理* @author    andy
*/import { useRoutes, Navigate } from 'react-router-dom'import Error from '@views/error/404'// 批量导入modules路由
const modules = import.meta.glob('./modules/*.jsx', { eager: true })
const patchRoutes = Object.keys(modules).map(key => modules[key].default).flat()// useRoutes集中式路由配置
export const routes = [{path: '/',element: <Navigate to="/home" replace={true} />,meta: {isWhite: true // 路由白名单}},...patchRoutes,// 404模块 path="*"不能省略{path: '*',element: <Error />,meta: {isWhite: true}}
]const Router = () => useRoutes(routes)export default Router

lazyload.jsx懒加载

import { Suspense } from 'react'
import { Spin } from '@arco-design/web-react'
import NprogressLoading from './nprogress'// 加载提示
const SpinLoading = () => {return (<Spintip='loading...'style={{width: '100%'}}/>)
}// 延迟加载
const lazyload = LazyComponent => {// React 16.6 新增了<Suspense>组件,懒加载的模式需要我们给他加上一层 Loading的提示加载组件// return <Suspense fallback={<SpinLoading />}><LazyComponent /></Suspense>return <Suspense fallback={<NprogressLoading />}><LazyComponent /></Suspense>
}export default lazyload

nprogress.jsx加载进度条

import { Component } from 'react'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'export default class NprogressLoading extends Component {constructor(props) {super(props)NProgress.set(.4)NProgress.start()}componentDidMount() {NProgress.done()}render() {return <div />}
}
/*** 主路由配置* @author Hs
*/import { lazy } from 'react'
import {IconHome, IconDashboard, IconLink, IconCommand, IconUserGroup, IconLock,IconMenu, IconSafe, IconBug, IconHighlight, IconUnorderedList, IconStop
} from '@arco-design/web-react/icon'
import Layout from '@/layouts'
import Blank from '@/layouts/blank'
import lazyload from '../lazyload'export default [/*首页模块*/{path: '/home',key: '/home', // 用于Menu组件跳转路由地址element: <Layout />,meta: {// icon: 've-icon-home', // 菜单图标icon: <IconHome />,name: 'layout__main-menu__home', // i18n国际化标题title: '主页',isAuth: true, // 需要鉴权isHidden: false, // 是否隐藏菜单isAffix: true // 固定tabview标签栏(不可关闭)},children: [{key: '/home',index: true,element: lazyload(lazy(() => import('@views/home'))),meta: {// icon: 've-icon-home',icon: <IconHome />,name: 'layout__main-menu__home-index',title: '首页',isAuth: true}},// 工作台{path: 'dashboard',key: '/home/dashboard',element: lazyload(lazy(() => import('@views/home/dashboard'))),meta: {// icon: 've-icon-computer',icon: <IconDashboard />,name: 'layout__main-menu__home-workplace',title: '工作台',isAuth: true}},// 外部链接{path: 'https://react.dev/',key: 'https://react.dev/',meta: {// icon: 've-icon-clip',icon: <IconLink />,name: 'layout__main-menu__home-apidocs',title: 'react.js官方文档',rootRoute: '/home'}}]},/*组件模块*/{...},/*用户管理模块*/{...},/*权限模块*/{...},/*错误模块*/{...}
]

路由配置参数:

/*** @description 路由参数说明* @param path ==> 路由地址标识* @param key ==> 用于Menu组件跳转路由地址* @param redirect ==> 重定向地址* @param element ==> 视图页面路径* 菜单信息(meta)*         @param meta.icon ==> 菜单图标*         @param meta.title ==> 菜单标题*         @param meta.name ==> i18n国际化标题*         @param meta.roles ==> 页面权限 ['admin', 'dev', 'test']*         @param meta.isAuth ==> 是否需要验证*         @param meta.isHidden ==> 是否隐藏页面*         @param meta.isAffix ==> 是否固定标签(tabs标签栏不能关闭)* */

react18路由菜单RouterMenu

在这里插入图片描述
如上图:react-admin提供了三种不同menu风格样式。

<RouteMenu rootRouteEnable={false} /><RouteMenu rootRouteEnable /><RouteMenu rootRouteEnable mode="horizontal" />

Menu.jsx路由模板

/*** 路由菜单模板
*/import './index.scss'
import { useState, useMemo, useEffect } from 'react'
import { useNavigate, useLocation } from 'react-router-dom'
import { Menu } from '@arco-design/web-react'
import Icon from '@components/Icon'
import RouteSubMenu from './submenu'
import { routes } from '@/routers'
import { getCurrentRootRoute, findParentRoute } from '@/hooks/useRoutes'
import Locales from '@/locales'export default function RouteMenu(props) {const {// 菜单类型(垂直vertical 水平菜单horizontal 弹出pop)mode = 'vertical',// 菜单风格('light' | 'dark')theme = 'light',// 是否开启一级路由菜单rootRouteEnable = false,style = {}} = propsconst navigate = useNavigate()const { pathname } = useLocation()const t = Locales()const [openKeys, setOpenKeys] = useState([])const rootRoute = getCurrentRootRoute()const filterRoutes = routes.filter(item => !item?.meta?.isWhite)const menuRoutes = useMemo(() => {if(rootRouteEnable) {return filterRoutes}// 过滤一级菜单return filterRoutes.find(item => item.path == rootRoute && item.children)?.children}, [pathname])useEffect(() => {setOpenKeys(getKeys(pathname))}, [pathname])// 获取选中菜单路由keys数组const getKeys = (key) => {return findParentRoute(menuRoutes, key)?.map(item => item?.key)}const handleNavigate = (key) => {const reg = /[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/if(reg.test(key)) {window.open(key)}else {navigate(key)}}return (<MenuclassName="ra__menus"mode={mode}theme={theme}selectedKeys={[pathname]}openKeys={openKeys}levelIndent={28}style={{ ...style }}onClickMenuItem={handleNavigate}onClickSubMenu={(_, openKeys) => {setOpenKeys(openKeys)}}>{ menuRoutes.map(item => {if(item?.children) {return RouteSubMenu(item, t)}return (!item?.meta?.isHidden &&<Menu.Item className="ra__menuItem" key={item.redirect || item.key}>{ item?.meta?.icon && <Icon name={item.meta.icon} size={18} style={{marginRight: 10}} /> }{ item?.meta?.name && <span>{t[item.meta.name]}</span> }</Menu.Item>)})}</Menu>)
}

Zustand:基于react新状态管理库

在这里插入图片描述

/*** react18状态管理库Zustand4,中间件persist本地持久化存储
*/
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'
import { generate, getRgbStr } from '@arco-design/color'export const appStore = create(persist((set, get) => ({// 语言(中文zh-CN 英文en 繁体字zh-TW)lang: 'zh-CN',// 角色类型 roles: ['admin'] / roles: ['admin', 'dev'] / roles: ['dev', test']roles: ["dev"],// 配置信息config: {// 布局(分栏columns 纵向vertical 横向transverse)layout: 'columns',// 模式(亮色light - 暗黑dark)mode: 'light',// 主题色theme: '#3491FA',// 是否折叠菜单collapsed: false,// 开启面包屑导航breadcrumb: true,// 开启标签栏tabsview: true,tabRoutes: [],// 显示搜索showSearch: true,// 显示全屏showFullscreen: true,// 显示语言showLang: true,// 显示公告showNotice: true,// 显示底部showFooter: false},// 更新配置updateConfig: (key, value) => set({config: { ...get().config, [key]: value }}),// 设置角色setRoles: (roles) => set({roles}),// 设置多语言setLang: (lang) => set({lang}),// 设置主题模式setMode: (mode) => {if(mode == 'dark') {// 设置为暗黑主题document.body.setAttribute('arco-theme', 'dark')}else {// 恢复亮色主题document.body.removeAttribute('arco-theme')}get().updateConfig('mode', mode)},// 设置主题样式setTheme: (theme) => {const colors = generate(theme, { list: true })colors.map((item, index) => {const rgbStr = getRgbStr(item)document.body.style.setProperty(`--arcoblue-${index + 1}`, rgbStr)})get().updateConfig('theme', theme)}}),{name: 'appState',// name: 'app-store', // name of the item in the storage (must be unique)// storage: createJSONStorage(() => sessionStorage), // by default, 'localStorage'})
)

react多语言配置i18n

在这里插入图片描述

在这里插入图片描述

/*** 国际化配置* @author YXY*/import { appStore } from '@/store/app'// 引入语言配置
import enUS from './en-US'
import zhCN from './zh-CN'
import zhTW from './zh-TW'export const locales = {'en': enUS,'zh-CN': zhCN,'zh-TW': zhTW
}export default (locale) => {const appState = appStore()const lang = appState.lang || 'zh-CN'return (locale || locales)[lang] || {}
}

lang.jsx语言配置

import { Dropdown, Menu, Button } from '@arco-design/web-react'
import Icon from '@components/Icon'
import { appStore } from '@/store/app'export default function Lang() {const { lang, setLang } = appStore()const handleLang = val => {setLang(val)}return (<Dropdownposition="bottom"droplist={<Menu className="radmin__dropdownLang" defaultSelectedKeys={[lang]} onClickMenuItem={handleLang}><Menu.Item key='zh-CN'>简体中文 <span>zh-CN</span></Menu.Item><Menu.Item key="zh-TW">繁体字 <span>zh-TW</span></Menu.Item><Menu.Item key="en">英文 <span>en</span></Menu.Item></Menu>}><Buttonshape="circle"size="small"icon={<Icon name="ve-icon-lang" />}/></Dropdown>)
}

Tabs路由菜单栏

在这里插入图片描述

<TabsactiveTab={pathname}editableshowAddButton={false}onDeleteTab={key => delTabs(key)}
>{ tabRoutes.map(item => (<Tabs.TabPaneclosable={!item?.meta?.isAffix}key={item?.redirect || item?.key}title={<Dropdowntrigger='contextMenu'position='bl'droplist={<Menu className="ra__dropdownContext" onClickMenuItem={(key, e) => handleClickMenuItem(key, e, item)}><Menu.Item key="close" disabled={item?.meta?.isAffix}><Icon name="ve-icon-close" />{t['tabview__contextmenu-close']}</Menu.Item><Menu.Item key="closeLeft" disabled={isFirstTab()}><Icon name="ve-icon-prev" />{t['tabview__contextmenu-closeleft']}</Menu.Item><Menu.Item key="closeRight" disabled={isLastTab()}><Icon name="ve-icon-next" />{t['tabview__contextmenu-closeright']}</Menu.Item><Menu.Item key="closeOther"><Icon name="ve-icon-reset" />{t['tabview__contextmenu-closeother']}</Menu.Item><Menu.Item key="closeAll"><Icon name="ve-icon-close-circle-o" />{t['tabview__contextmenu-closeall']}</Menu.Item></Menu>}onVisibleChange={visible=>handleOpenContextMenu(visible, item)}><span className="ra__tabsview-title" onClick={() => navigate(item?.redirect || item?.key)}><TabIcon path={item?.key} />{ t[item?.meta?.name] }</span></Dropdown>}/>))}
</Tabs>

好了,以上就是react18+vite4+arco构建后台系统模板的一些分享了。

webchat-react基于react18+arco网页版聊天实例

electron-chatgpt基于electron25+vite4仿制ChatGPT模板

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(原创)实现左侧TextView宽度自适应并且可以显示右侧TextView的布局

效果展示 先来看看上面的效果 左侧的文字宽度是自适应的&#xff0c;但是右侧又有一个TextView 左侧的文字被限制不能把右侧的挤出屏幕外面 所以如果左侧文字超过指定宽度后多余部分就用省略号表示 实际开发中这种情况在一些列表的item中用的比较多 但实际实现的时候会发现 左侧…

常见问题-找不到vcruntime140.dll无法继续执行代码解决方案

本文将介绍五种不同的解决方案&#xff0c;帮助大家解决这个问题。 首先&#xff0c;我们需要了解为什么会出现找不到vcruntime140.dll的情况。这种情况通常是由于以下几个原因导致的&#xff1a; 1. 系统环境变量设置不正确&#xff1a;系统环境变量中可能没有包含vcruntime…

C++QT---QT-day3

#include "widget.h" #include "ui_widget.h" //需要在.pro文件第一行加 texttospeechWidget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);ui->lineEdit->setPlaceholderText("时:分:秒");//设…

华为ICT——云计算基础知识、计算类技术听课笔记

ICT(information and communications technology):信息与通信技术 传统IT架构缺点 TCO&#xff1a;总体拥有成本 云计算模式 云计算价值 云计算通用点 虚拟化技术&#xff1a;将单台物理服务器虚拟为多台虚拟机使用&#xff0c;多台虚拟机共享物理服务器硬件资源。 虚拟化本质…

服务器往浏览器推消息(SSE)应用

1&#xff0c;SSE 和 WebSocket 对比 SSE&#xff08;服务器发送事件&#xff09; SSE是一种基于HTTP的单向通信机制&#xff0c;用于服务器向客户端推送数据。它的工作原理如下&#xff1a; 建立连接&#xff1a;客户端通过发送HTTP请求与服务器建立连接。在请求中&#xff…

Python特征分析重要性的常用方法

前言 特征重要性分析用于了解每个特征(变量或输入)对于做出预测的有用性或价值。目标是确定对模型输出影响最大的最重要的特征&#xff0c;它是机器学习中经常使用的一种方法。 为什么特征重要性分析很重要? 如果有一个包含数十个甚至数百个特征的数据集&#xff0c;每个特征…

Oracle database 开启归档日志 archivelog

Oracle database 开启归档日志 archivelog 归档日志模式 (Archivelog Mode)。归档日志模式是一种数据库运行模式&#xff0c;它允许数据库将日志文件保存到归档日志目录中&#xff0c;以便在需要时进行恢复和还原操作。通过开启归档日志模式&#xff0c;可以提高数据库的可靠性…

驱动day2:LED灯实现三盏灯的亮灭

head.h #ifndef __HEAD_H__ #define __HEAD_H__ #define PHY_PE_MODER 0x50006000 #define PHY_PF_MODER 0x50007000 #define PHY_PE_ODR 0x50006014 #define PHY_PF_ODR 0x50007014 #define PHY_RCC 0x50000A28#endif 应用程序 #include <stdio.h> #include <sys/…

通讯网关软件026——利用CommGate X2ORACLE-U实现OPC UA数据转入ORACLE

本文介绍利用CommGate X2ORACLE-U实将OPC UA数据源中的数据转入到ORACLE数据库。CommGate X2ORACLE-U是宁波科安网信开发的网关软件&#xff0c;软件可以登录到网信智汇(http://wangxinzhihui.com)下载。 【案例】如下图所示&#xff0c;将OPC UA数据源的数据写入到ORACLE数据…

利用Nginx可视化管理工具+Cpolar实现本地服务远程访问

文章目录 前言1. docker 一键安装2. 本地访问3. Linux 安装cpolar4. 配置公网访问地址5. 公网远程访问6. 固定公网地址 前言 Nginx Proxy Manager 是一个开源的反向代理工具&#xff0c;不需要了解太多 Nginx 或 Letsencrypt 的相关知识&#xff0c;即可快速将你的服务暴露到外…

驱动编写应用程序控制三盏灯亮灭

应用程序 #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <string.h> int main(int argc, char const *argv[]) {char buf[128] {0};int fd open("/dev/mych…

59 分割等和子集

分割等和子集 NP 完全问题&#xff08;01背包&#xff09;题解1 二维DP题解2 空间优化DP&#xff08;改为1D&#xff09; 给你一个只包含正整数的非空数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&a…

从头开始机器学习:逻辑回归

一、说明 本篇实现线性回归的先决知识是&#xff1a;基本线性代数&#xff0c;微积分&#xff08;偏导数&#xff09;、梯度和、Python &#xff08;NumPy&#xff09;&#xff1b;从线性方程入手&#xff0c;逐渐理解线性回归预测问题。 二、逻辑回归简介 我们将以我们在线性回…

Unity3D Shader新手入门教程:3D溶解与腐蚀特效详解

引言 在游戏开发中&#xff0c;特效是非常重要的一部分&#xff0c;它能够增加游戏的趣味性和可玩性。其中&#xff0c;Shader特效是一种非常常见和常用的特效&#xff0c;它能够通过改变物体表面的渲染方式来实现各种各样的特效效果。本文将详细介绍Unity3D中的Shader 3D溶解与…

uview组件使用笔记

图标样式 修改图标的样式 通过color参数修改图标的颜色通过size参数修改图标的大小&#xff0c;单位为rpx 效果图 <u-icon name"photo" color"#2979ff" size"28"></u-icon>图片图标 1.3.0 这里说的图片图标&#xff0c;指的是小…

基于金枪鱼群优化的BP神经网络(分类应用) - 附代码

基于金枪鱼群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于金枪鱼群优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.金枪鱼群优化BP神经网络3.1 BP神经网络参数设置3.2 金枪鱼群算法应用 4.测试结果…

接口自动化测试持续集成,Soapui接口功能测试参数化

按照自动化测试分层实现的原理&#xff0c;每一层的脚本实现都要进行参数化&#xff0c;自动化的目标就是要实现脚本代码与测试数据分离。当测试数据进行调整的时候不会对脚本的实现带来震荡&#xff0c;从而提高脚本的稳定性与灵活度&#xff0c;降低脚本的维护成本。Soapui最…

【学习笔记】RabbitMQ01:基础概念认识以及快速部署

参考资料 RabbitMQ官方网站RabbitMQ官方文档噼咔噼咔-动力节点教程 文章目录 一、认识RabbitMQ1.1 消息中间件&#xff08;MQ Message Queue 消息队列1.2 主流的消息中间件1.3 MQ的应用场景1.3.1 异步处理1.3.2 系统解耦1.3.3 流量削峰1.3.4 日志处理 二、RabbitMQ运行环境搭建…

【C语言进阶(14)】程序的编译与链接

文章目录 前言Ⅰ 程序的翻译环境1. 编译的过程2. 链接的过程 Ⅱ 程序的执行环境Ⅲ 预定义符号Ⅳ 预处理指令 #define1. #define 定义标识符2. #define 定义宏3. #define 替换规则 Ⅴ 预处理操作符 # 和1. # 操作符2. ## 操作符 Ⅵ 宏和函数的对比Ⅶ 预处理指令 #undefⅧ 条件编…