使用vite+react+ts+Ant Design开发后台管理项目(二)
前言
本文将引导开发者从零基础开始,运用vite、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈,构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导,文章旨在为开发者揭示如何利用这些技术工具,从项目构思到最终实现的全过程,提供清晰的开发思路和实用的技术应用技巧。
项目gitee地址:lbking666666/enqi-admin
本系列文章:
- 使用vite+react+ts+Ant Design开发后台管理项目(一)
- 使用vite+react+ts+Ant Design开发后台管理项目(二)
- 使用vite+react+ts+Ant Design开发后台管理项目(三)
- 使用vite+react+ts+Ant Design开发后台管理项目(四)
使用redux
上一章布局组件拆分前组件侧边栏和头部需要有交互,根据一个响应式的变量collapsed来进行交互的,目前已经把这两部分拆分到了两个子组件header.tsx和sider.tsx中,此时需要引入redux来对状态进行管理。
引入redux和 @reduxjs/toolkit
# 如果你使用 npm:npm install react-redux @reduxjs/toolkit -S# 或者你使用 Yarn:
yarn add react-redux @reduxjs/toolkit
为什么使用 Redux Toolkit
Redux Toolkit 是官方推荐的编写 Redux 逻辑的方法。它围绕 Redux 核心,并包含我们认为对于构建 Redux 应用必不可少的软件包和功能。Redux Toolkit 简化了大多数 Redux 任务,防止了常见错误,并使编写 Redux 应用程序更加容易。
无论你是一个想要开发第一个 Redux 应用的新手,还是想要简化已有应用经验老道的老手,Redux Toolkit 都能帮你写出更好的 Redux 代码。
创建store文件
首先在src文件夹下创建store文件夹,新建一个index.ts文件
//store/index.ts
import { configureStore } from "@reduxjs/toolkit";
//处理eslint报错
/* eslint-disable @typescript-eslint/no-unused-vars */
const store = configureStore({reducer: {},
});// 从 store 本身推断 `RootState` 和 `AppDispatch` 类型
export type RootState = ReturnType<typeof store.getState>;
// 推断类型:{posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;export default store;
创建reducer
在store文件夹下新建reducers文件夹,新增一个文件global.ts
//global.ts
import { createSlice } from "@reduxjs/toolkit";
import type { RootState } from "@/store/index.ts";// 定义初始 state 的类型
interface GlobalState {collapsed: boolean;
}
// 使用该类型定义初始 state
const initialState: GlobalState = {collapsed: false
};
// 创建 slice
export const globalSlice = createSlice({name: "global",// 名称initialState,// 初始 statereducers: {// 定义 reducer 函数,该函数接受 state 和 action 作为参数setCollapsed: (state) => {// 更新 statestate.collapsed = !state.collapsed;},},
});// 为每个 case reducer 函数生成 Action creators
export const { setCollapsed } = globalSlice.actions;
// selectors 等其他代码可以使用导入的 `RootState` 类型
export const selectCollapsed = (state: RootState) => state.global.collapsed;
// 导出 reducer
export default globalSlice.reducer;
使用 Hooks 类型
尽管你可以将 RootState 和 AppDispatch 类型导入每个组件, 更好的方式是创建 useDispatch 和 useSelector 钩子的类型定义,以便在你的应用程序中使用
- 对于
useSelector,它不需要你每次输入(state: RootState) - 对于
useDispatch,默认的 Dispatch 类型不知道 thunk 。为了正确调度 thunk ,你需要使用 store 中包含 thunk 中间件类型的特定自定义AppDispatch类型,并将其与useDispatch一起使用。添加一个预先输入的useDispatch钩子可以防止你忘记在需要的地方导入AppDispatch。
由于这些是实际变量,而不是类型,因此将它们定义在单独的文件中很重要,而不是 store 设置文件。这允许你将它们导入到需要使用挂钩的任何组件文件中,并避免潜在的循环导入依赖问题。
定义 Hooks 类型
在src文件夹下新增hooks文件夹,新增文件UseGlobal.hooks.ts
//UseGlobal.hooks
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import type { RootState, AppDispatch } from '@/store/index';// 在整个应用程序中使用,而不是简单的 `useDispatch` 和 `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
引入globalReducer
修改store文件夹下的index.ts
//store/index.tsimport { configureStore } from "@reduxjs/toolkit";
import globalReducer from "./reducers/global";
//处理eslint报错
/* eslint-disable @typescript-eslint/no-unused-vars */
const store = configureStore({reducer: {global: globalReducer,},
});// 从 store 本身推断 `RootState` 和 `AppDispatch` 类型
export type RootState = ReturnType<typeof store.getState>;
// 推断类型:{posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;export default store;
在组件中使用
上一章中的左侧组件和头部组件中有一个响应式变量collapsed,现在可以使用redux状态来处理,根据Ant Design的代码和组件拆分分析,两个组件都需要使用这个collapsed状态所以放在layout文件夹下的index.tsx中获取当前的collapsed值,然后通过给组件传参的形式同步两个组件的状态
1.布局组件改造
修改layout文件夹下的index.tsx内容
//layout/index.tsx
import React from "react";
import { Layout } from "antd";
import { useAppSelector} from '@/hooks/UseGlobal.hooks';
import { selectCollapsed } from "@/store/reducers/global";
import AppHeader from "./header";
import AppSider from "./sider";
import AppMain from "./main";const App: React.FC = () => {// 获取全局状态 collapsed 可以使用以下两种方式中的一种//const collapsed:boolean = useAppSelector((state) => state.global.collapsed);const collapsed: boolean = useAppSelector(selectCollapsed);return (<Layout className="app-layout "><AppSider collapsed={collapsed} /><Layout><AppHeader collapsed={collapsed} /><AppMain /></Layout></Layout>);
};export default App;
2.侧边组件改造
修改layout文件夹下的sider.tsx
//layout/sider.tsx
import React from "react";
import {UploadOutlined,UserOutlined,VideoCameraOutlined,
} from "@ant-design/icons";
import { Layout, Menu } from "antd";
const { Sider } = Layout;interface AppSiderProps {collapsed: boolean;
}
const AppSider: React.FC<AppSiderProps> = ({ collapsed }) => {return (<Sider trigger={null} collapsible collapsed={collapsed}><div className="demo-logo-vertical" /><Menutheme="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>);
};
export default AppSider;
3.头部组件改造
修改layout文件夹下的header.tsx
//layout/header.tsx
import React from "react";
import { Button, Layout, theme } from "antd";
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
const { Header } = Layout;
interface AppSiderProps {collapsed: boolean;
}
const AppHeader: React.FC<AppSiderProps> = ({ collapsed }) => {const {token: { colorBgContainer },} = theme.useToken();return (<Header style={{ padding: 0, background: colorBgContainer }}><Buttontype="text"icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}style={{fontSize: "16px",width: 64,height: 64,}}/></Header>);
};
export default AppHeader;
4.添加事件

如上图所示点击红框的按钮需要做到伸缩左侧的侧边栏,固需要在这里添加事件
代码如下
//layout/header.tsx
import React from "react";
import { Button, Layout, theme } from "antd";
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
import { useAppDispatch } from '@/hooks/UseGlobal.hooks';
import { setCollapsed } from "@/store/reducers/global";
const { Header } = Layout;
interface AppSiderProps {collapsed: boolean;
}
const AppHeader: React.FC<AppSiderProps> = ({ collapsed }) => {const {token: { colorBgContainer },} = theme.useToken();const dispatch = useAppDispatch();const handleCollapsed = () => {//更新全局状态 collapseddispatch(setCollapsed());};return (<Header style={{ padding: 0, background: colorBgContainer }}><Buttontype="text"icon={collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}style={{fontSize: "16px",width: 64,height: 64,}}onClick={handleCollapsed}/></Header>);
};
export default AppHeader;
查看效果,点击按钮左侧边栏可以伸缩

后续
本篇文章为项目引入了redux和怎么在项目中使用做了说明,代码已经同步到了gitee仓库,下一篇会丰富头部组件,使用redux增加主题风格配置和左侧菜单抽离为单独组件根据不同的菜单点击进入不同组件
相关文章:
使用vite+react+ts+Ant Design开发后台管理项目(二)
前言 本文将引导开发者从零基础开始,运用vite、react、react-router、react-redux、Ant Design、less、tailwindcss、axios等前沿技术栈,构建一个高效、响应式的后台管理系统。通过详细的步骤和实践指导,文章旨在为开发者揭示如何利用这些技术…...
C++之 string(中)
C之 string string类对象的容量操作 resize 将有效字符的个数该成n个,多出的空间用字符c填充 虽然在string里用的不多,但是在vector里面常见 这里有三种情况: 1)resize小于当前的size 2)resize大于当前的size,小于capacity …...
双向链表的基本结构及功能实现
1.基本结构: 双向链表是一种链表数据结构,它由一系列节点组成,每个节点包含三个部分: (1).数据域:存储节点的数据 (2).前驱指针:指向前一个节点 (3).后驱指针:指向下一个节点 2.基本特性: 双向链接: 与单向链表…...
stm32定时触发软件中断
这里使用定时器作为延时,单位为秒,使用exti的软件触发方式,配置见代码,在main里进行触发软件中断 代码 #include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "misc.h" #include "…...
blender设置背景图怎么添加?blender云渲染选择
Blender是一款功能强大的3D建模软件,它以流畅的操作体验和直观的用户界面而闻名。使用Blender,你可以轻松地为你的3D模型添加背景图片。 以下是具体的操作步骤: 1、启动Blender:首先,打开Blender软件。访问添加菜单&a…...
MMD模型及动作一键完美导入UE5-Blender方案(三)
1、下载并安装blender_mmd_tools插件 1、下载并安装Blender,Blender,下载Blender3.6,下载太新的版本可能会跟blender_mmd_tools不匹配 2、github下载blender_mmd_tools:https://github.com/UuuNyaa/blender_mmd_tools/ 3、Edit->Preference->Add ons->Install F…...
网络安全自学入门:(超详细)从入门到精通学习路线规划,学完即可就业
很多人上来就说想学习黑客,但是连方向都没搞清楚就开始学习,最终也只是会无疾而终!黑客是一个大的概念,里面包含了许多方向,不同的方向需要学习的内容也不一样。 算上从学校开始学习,已经在网安这条路上走…...
如何在O2OA中使用ElementUI组件进行审批流程工作表单设计
本文主要介绍如何在O2OA中进行审批流程表单或者工作流表单设计,O2OA主要采用拖拽可视化开发的方式完成流程表单的设计和配置,不需要过多的代码编写,业务人员可以直接进行修改操作。 在流程表单设计界面,可以在左边的工具栏找到Ele…...
三、LLM应用开发准备工作
LLM应用开发准备工作 开发基础开发工具大模型kxswkey的配置与使用工具推荐结语 开发基础 最好具备一定的Python开发基础,不需要特别深 如果不具备,可以先学习一下基础知识(概念),比如Python环境管理、包管理与使用、基…...
机器学习-可解释性机器学习:随机森林与fastshap的可视化模型解析
可解释性机器学习是指使机器学习模型的决策过程透明化,帮助用户理解模型如何得出特定结果。随机森林和 FastSHAP 是常用的工具,以下是对它们的简要解析和可视化方法。 随机森林 1. 概述 随机森林是一种集成学习方法,通过构建多个决策树并结…...
使用Assimp加载glb/gltf文件,然后使用Qt3D来渲染
文章目录 1.代码2.说明2.1.调用2.2.关于贴图 1.代码 ModelLoader.h #ifndef MODELLOADER_H #define MODELLOADER_H#include <QObject> #include <Qt3DRender> #include <QVector3D> #include <QGeometry>#include <assimp/Importer.hpp> #incl…...
vue实现左侧数据拖拽到右侧区域,且左侧数据保留且左侧数据不能互相拖拽改变顺序
一、案例效果 二、案例代码 封装左侧抽屉 DrawerSearch.vue<template><div><mtd-form :model="formDrawerSearch" ref="formCustom" inline><mtd-form-item><mtd-inputtype="text"v-model="formDrawerSearch.ho…...
人工智能与机器学习原理精解【21】
文章目录 SVM求两线段上距离最近的两个点问题描述:距离函数:解法:具体步骤:特别注意:示例代码 SVM思想的介入1. **SVM 的基本思想**超平面: 2. **分类间隔(Margin)**1. **分类间隔的…...
【MySQL 01】数据库基础
目录 1.数据库是什么 2.基本操作 数据库服务器连接操作 数据库和数据库表的创建 服务器,数据库,表关系 数据逻辑存储 3.MySQL架构 4.SQL分类 5.存储引擎 1.数据库是什么 mysql&&mysqld: mysql:这通常指的是 MySQL …...
C语言字符学习中级使用库解决问题
学习C语言中的字符处理,对于初学者来说,理解字符的基本概念以及如何进行操作是非常重要的。字符处理是指对单个字符或一组字符(字符串)的操作。为了更好地理解,下面从基础开始介绍,并结合一些常用的函数和示…...
网络管理:网络故障排查指南
在现代IT环境中,网络故障是不可避免的。快速、有效地排查和解决网络故障是确保业务连续性和用户满意度的关键。本文将详细介绍网络故障排查的基本方法和步骤,确保内容通俗易懂,并配以代码示例和必要的图片说明。 一、网络故障排查的基本步骤 确认故障现象 确认用户报告的故…...
Springboot常见问题(bean找不到)
如图错误显示userMapper bean没有找到。 解决方案: mapper包位置有问题:因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题: 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…...
架构设计笔记-5-软件工程基础知识
知识要点 按软件过程活动,将软件工具分为软件开发工具、软件维护工具、软件管理和软件支持工具。 软件开发工具:需求分析工具、设计工具、编码与排错工具。 软件维护工具:版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工…...
Solidity——抽象合约和接口详解
🚀本系列文章为个人学习笔记,目的是巩固知识并记录我的学习过程及理解。文笔和排版可能拙劣,望见谅。 Solidity中的抽象合约和接口详解 目录 什么是抽象合约?抽象合约的语法接口(Interface)的定义接口的语…...
Fyne ( go跨平台GUI )中文文档-入门(一)
本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI )…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
ubuntu22.04 安装docker 和docker-compose
首先你要确保没有docker环境或者使用命令删掉docker sudo apt-get remove docker docker-engine docker.io containerd runc安装docker 更新软件环境 sudo apt update sudo apt upgrade下载docker依赖和GPG 密钥 # 依赖 apt-get install ca-certificates curl gnupg lsb-rel…...
