从0开始的中后台管理系统-5(userList动态展示以及上传图片和弹出创建用户表单)

        项目用的都是antd组件,这里的userList组件展示的表单组件的数据直接get请求拿过来展示的,这里随机生成了50个用户只是为了展示表单的api设置。首先就是表单展示需要两个参数current和pageSize两个属性控制表单的最大分页和当前页面。那么我们就设置初始值然后通过访问服务器返回来一些数据,这里我们不用服务器返回的,只是用自己设置的一些数据去展示效果,还有onChange自带的api监听page和pageSize去获取变化后的然后更新就好了,.直接上代码。

1.userList动态展示

        效果图

import React, { useState, useEffect, useRef } from 'react'
import type { PageParams, User } from '@/types/api'
import type { TableColumnsType } from 'antd'
import { Button, Table, Form, Input, Select, Space } from 'antd'
import api from '@/api/index'
import { toLocalDate } from '@/utils'
import CreateUser from './CreateUser'
import type { IAction } from '@/types/modal'
export default function UserList() {const userRef = useRef<{open: (type: IAction, data?: User.UserItem) => void | undefined}>(null)//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容const [form] = Form.useForm()const [data, setData] = useState<User.UserItem[]>([])const [total, setTotal] = useState(0)const [pagination, setPagination] = useState({current: 1,pageSize: 10})// 获取用户列表const getUserList = async (params: PageParams) => {const values = form.getFieldsValue()const data = await api.getUserList({...values,pageNum: params.pageNum,pageSize: params.pageSize})const list = Array.from({ length: 51 }).fill({}).map((item: any) => {item = { ...data.list[0] }item.userId = Math.random()return item})setData(list) // 注意:接口返回结构要和这里匹配setTotal(list.length)setPagination({current: params.pageNum,pageSize: params.pageSize})}//创建const handleCreate = () => {userRef.current?.open('create')}//搜索const handleSearch = () => {getUserList({pageNum: 1,pageSize: pagination.pageSize})}//重置 表单const handleReset = () => {form.resetFields()}// 组件挂载时调用useEffect(() => {getUserList({pageNum: pagination.current,pageSize: pagination.pageSize})}, [pagination.current, pagination.pageSize])const columns: TableColumnsType<User.UserItem> = [{title: '用户ID',dataIndex: 'userId',key: 'userId'},{title: '用户名称',dataIndex: 'userName',key: 'userName'},{title: '用户邮箱',dataIndex: 'userEmail',key: 'userEmail'},{title: '用户角色',dataIndex: 'role',key: 'role',render(role: number) {return {0: '超级管理员',1: '管理员',2: '体验管理员',3: '普通用户'}[role]}},{title: '用户状态',dataIndex: 'state',key: 'state',render(state: number) {return {1: '在职',2: '离职',3: '试用期'}[state]}},{title: '注册时间',dataIndex: 'create', // 你的字段是 create,不是 createTimekey: 'create',render(createTime: string) {return toLocalDate(createTime)}},{title: '操作',key: 'action',render(_, record) {return (<Space><Button type='text'>编辑</Button><Button type='text' danger>删除</Button></Space>)}}]return (<div className='user-list'><Formform={form}className='search-form'layout='inline'initialValues={{ state: 0 }}><Form.Item name='userId' label='用户ID'><Input placeholder='请输入用户ID' /></Form.Item><Form.Item name='userName' label='用户名称'><Input placeholder='请输入用户名称' /></Form.Item><Form.Item name='state' label='状态'><Select style={{ width: 120 }}><Select.Option value={0}>所有</Select.Option><Select.Option value={1}>在职</Select.Option><Select.Option value={2}>试用</Select.Option><Select.Option value={3}>离职</Select.Option></Select></Form.Item><Form.Item><Space><Button onClick={handleSearch} type='primary' className='mr10'>搜索</Button><Button onClick={handleReset} type='default'>重置</Button></Space></Form.Item></Form><div className='base-table'><div className='header-wrapper'><div className='title'>用户列表</div><div className='action'><Button type='primary' onClick={handleCreate}>新增</Button><Button type='primary' danger>批量删除</Button></div></div><TablerowKey='userId' // 保证每行有唯一 keypagination={{position: ['bottomRight'],current: pagination.current,pageSize: pagination.pageSize,total: total,showQuickJumper: true,showSizeChanger: true,showTotal: function (total) {return 总共:${total}条},onChange: (page, pageSize) => {setPagination({current: page,pageSize: pageSize})}}}borderedrowSelection={{ type: 'checkbox' }}dataSource={data}columns={columns}/></div><CreateUsermRef={userRef}updata={() => {getUserList({pageNum: 1,pageSize: 10})}}/></div>)
}

2.创建表单以及上传头像功能(点击新增弹出取消关闭以及发送成功关闭)

        效果图

        

       静态的展示就不说了,用户头像我们在上传之前,

        

                无非就是上传之后服务器发送回来url然后去替换展示,然后三元表达式就实现了。主要是怎么可以实现点击新增跳出来子组件也就是创建表单。

        首先我们可以设置子组件默认不展示的,也就是open我们设置为关闭,我们希望父组件可以操作子组件的属性,而且我们还希望添加成功后立马重新加载获取新列表,那么我们就给子组件传递参数,一个我们设置的ref扔过去,以及一个更新方法。

        然后子组件mRef绑定父组件设置的ref那么就拿到了子组件的DOM元素了,但是方法还是拿不到,也就是我们没办法去操作子组件设置的vibale状态去控制子组件的展示和关闭,那么子组件用useImperativehandle暴露一个open方法,然后open方法可以接收一个类型,因为这个表单我们要在增加更新都需要用到,然后更新vision,这样就实现了完整了逻辑。上代码。

import React, { useState, useEffect, useRef } from 'react'
import type { PageParams, User } from '@/types/api'
import type { TableColumnsType } from 'antd'
import { Button, Table, Form, Input, Select, Space } from 'antd'
import api from '@/api/index'
import { toLocalDate } from '@/utils'
import CreateUser from './CreateUser'
import type { IAction } from '@/types/modal'
export default function UserList() {const userRef = useRef<{open: (type: IAction, data?: User.UserItem) => void | undefined}>(null)//获取表单对象 用里面的方法 getFieldsValue获取表单中填写的内容const [form] = Form.useForm()const [data, setData] = useState<User.UserItem[]>([])const [total, setTotal] = useState(0)const [pagination, setPagination] = useState({current: 1,pageSize: 10})// 获取用户列表const getUserList = async (params: PageParams) => {const values = form.getFieldsValue()const data = await api.getUserList({...values,pageNum: params.pageNum,pageSize: params.pageSize})const list = Array.from({ length: 51 }).fill({}).map((item: any) => {item = { ...data.list[0] }item.userId = Math.random()return item})setData(list) // 注意:接口返回结构要和这里匹配setTotal(list.length)setPagination({current: params.pageNum,pageSize: params.pageSize})}//创建const handleCreate = () => {userRef.current?.open('create')}//搜索const handleSearch = () => {getUserList({pageNum: 1,pageSize: pagination.pageSize})}//重置 表单const handleReset = () => {form.resetFields()}// 组件挂载时调用useEffect(() => {getUserList({pageNum: pagination.current,pageSize: pagination.pageSize})}, [pagination.current, pagination.pageSize])const columns: TableColumnsType<User.UserItem> = [{title: '用户ID',dataIndex: 'userId',key: 'userId'},{title: '用户名称',dataIndex: 'userName',key: 'userName'},{title: '用户邮箱',dataIndex: 'userEmail',key: 'userEmail'},{title: '用户角色',dataIndex: 'role',key: 'role',render(role: number) {return {0: '超级管理员',1: '管理员',2: '体验管理员',3: '普通用户'}[role]}},{title: '用户状态',dataIndex: 'state',key: 'state',render(state: number) {return {1: '在职',2: '离职',3: '试用期'}[state]}},{title: '注册时间',dataIndex: 'create', // 你的字段是 create,不是 createTimekey: 'create',render(createTime: string) {return toLocalDate(createTime)}},{title: '操作',key: 'action',render(_, record) {return (<Space><Button type='text'>编辑</Button><Button type='text' danger>删除</Button></Space>)}}]return (<div className='user-list'><Formform={form}className='search-form'layout='inline'initialValues={{ state: 0 }}><Form.Item name='userId' label='用户ID'><Input placeholder='请输入用户ID' /></Form.Item><Form.Item name='userName' label='用户名称'><Input placeholder='请输入用户名称' /></Form.Item><Form.Item name='state' label='状态'><Select style={{ width: 120 }}><Select.Option value={0}>所有</Select.Option><Select.Option value={1}>在职</Select.Option><Select.Option value={2}>试用</Select.Option><Select.Option value={3}>离职</Select.Option></Select></Form.Item><Form.Item><Space><Button onClick={handleSearch} type='primary' className='mr10'>搜索</Button><Button onClick={handleReset} type='default'>重置</Button></Space></Form.Item></Form><div className='base-table'><div className='header-wrapper'><div className='title'>用户列表</div><div className='action'><Button type='primary' onClick={handleCreate}>新增</Button><Button type='primary' danger>批量删除</Button></div></div><TablerowKey='userId' // 保证每行有唯一 keypagination={{position: ['bottomRight'],current: pagination.current,pageSize: pagination.pageSize,total: total,showQuickJumper: true,showSizeChanger: true,showTotal: function (total) {return 总共:${total}条},onChange: (page, pageSize) => {setPagination({current: page,pageSize: pageSize})}}}borderedrowSelection={{ type: 'checkbox' }}dataSource={data}columns={columns}/></div><CreateUsermRef={userRef}updata={() => {getUserList({pageNum: 1,pageSize: 10})}}/></div>)
}

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

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

相关文章

Spring MVC REST API设计详解:从零构建高效接口

1. Spring MVC与REST API基础1.1 RESTful架构的六大约束详解RESTful架构是Roy Thomas Fielding在2000年博士论文中提出的软件架构风格&#xff0c;它包含六个核心约束&#xff0c;这些约束共同构成了RESTful API的设计原则。客户端-服务器约束&#xff08;Client-Server&#x…

基于STM32F030C8T6单片机实现与CH224Q诱骗芯片的I2C通信和电压输出配置

基于项目的需要,对STM32F030的IIC研究了几天,终于完成了通信,接下来具体实现如下: 本单片机使用的是PB8和PB9管脚进行实现,采用的是模拟的IIC进行 void MyI2C_W_SCL(uint8_t BitValue)//这三个函数将读写io口封装起来,增强可读性 { GPIO_WriteBit(GPIOB, GPIO_Pin_8…

TSMaster-C小程序使用

打开同星的TSMaster&#xff0c;推荐用32版本的&#xff0c;比64更稳定。同星的TSMaster的C小程序支持用户嵌入代码来控制CAN报文的收发逻辑。便于开发。点击设计里面的C小程序。 比如我现在想用小程序来实现继电器0先开后关开1s关1s&#xff0c;然后继电器1开1s关1s…如此往复…

XSS渗透测试原理/步骤/攻击方法/防御/常用语法

**核心概念回顾&#xff1a;**XSS漏洞一直被评估为web漏洞中危害较大的漏洞&#xff0c;在OWASP TOP10的排名中一直属于前三的江湖地位。XSS是一种发生在前端浏览器端的漏洞&#xff0c;所以其危害的对象也是前端用户。 形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处…

目标检测数据集 - 自动驾驶场景道路异常检测数据集下载「包含VOC、COCO、YOLO三种格式」

数据集介绍&#xff1a;自动驾驶场景道路异常检测数据集&#xff0c;真实场景高质量道路图片数据&#xff0c;涉及场景丰富&#xff0c;且类别丰富&#xff0c;划分为 "LMVs 轻型机动车&#xff08;汽车、摩托车、小型卡车、小型货车"、"HMVs 公交车、卡车、拖拉…

多模态新方向|从数据融合到场景落地,解锁视觉感知新范式

来gongzhonghao【图灵学术计算机论文辅导】&#xff0c;快速拿捏更多计算机SCI/CCF发文资讯&#xff5e;多模态学习&#xff08;Multimodal Learning&#xff09;是通过整合多种数据模态来提升模型对复杂场景感知与理解能力的技术&#xff0c;其核心是利用不同模态的互补性突破…

机器学习之随机森林

目录 一、什么是随机森林&#xff1f; 1. 从决策树到集成学习&#xff1a;为什么需要 "森林"&#xff1f; 2.什么是集成学习 二、随机森林的工作原理 三、随机森林构造过程 四、随机森林api介绍 五、随机森林的优缺点 六、垃圾邮件判断案例 1.数据集介绍 ​…

云平台运维工具 —— 阿里云原生工具

一、简介阿里云作为国内领先的云服务提供商&#xff0c;拥有一套完整的原生运维工具体系&#xff0c;这些工具与阿里云的各类服务深度融合&#xff0c;能够满足用户在资源部署、监控告警、权限管理、自动化运维等方面的需求。无论是简单的应用托管还是复杂的企业级架构&#xf…

Linux-Day10.系统安全保护web服务管理

今日目标&#xff1a;- 日志管理- 系统安全保护 SELinux&#xff08;重点&#xff09;- 构建基本web服务&#xff08;重点&#xff09;环境准备还原快照网络配置完成&#xff0c;开启虚拟机A与虚拟机B用真机连通虚拟机去操作&#xff0c;准本好Xshell一、常用的网络工具ip命令1…

解决:开启魔法后vscode pip命令不能安装中科大python镜像问题

闲言少叙&#xff0c;最终实现效果就是在开启魔法情况下&#xff0c;vscode命令行任何能通过中科大python镜像安装第三方库&#xff0c;又快又不消耗魔法流量。简单来说就两步&#x1f447;&#xff1a; 第一步&#xff1a;配置 pip.ini 中的代理 找到或创建 pip.ini 文件&…

优化Google Pubsub到GCS的文件整合策略

引言 在使用Google Cloud Platform (GCP) 的Pubsub服务时,我们常常会遇到将消息存储到Google Cloud Storage (GCS) 作为Avro文件的问题。本文将深入探讨如何优化Google Pubsub到GCS的文件整合策略,以避免每个消息都单独生成一个Avro文件,达到将多个消息整合到一个文件的目的…

基于铁头山羊STM32的平衡车电机转速开环闭环matlab仿真

基于铁头山羊STM32的平衡车电机转速开环闭环matlab仿真前言一、电机开环传递函数1.1 电机开环传递函数的零极点1.2 求系统的参数和绘制波特图二、增加PI控制器后系统开环传递函数三、电机系统闭环传递函数四、simulink仿真五、幅值裕度、相位裕度、相位穿越频率和截止频率&…

P1044 [NOIP 2003 普及组] 栈

P1044 [NOIP 2003 普及组] 栈 - 洛谷 题解来自洛谷题解&#xff0c;做笔记用 假设用一个函数来表示&#xff1a; x表示当前还未入栈的数字个数 y表示当前栈中的数字个数 orz&#xff0c;大佬们真的是很厉害&#xff0c;想着递推但是只拿了60分 #include <bits/stdc.h&g…

linux mysql 8.X主从复制

准备两台linux服务器,注意要锁ip我这里如上图 主库 192.168.5.5/24 从库 192.168.5.10/24 接下来确定mysql是否启动成功并且能从外部连接 主库从库主服务器配置 vim编辑主服务器配置 vim /etc/my.cnf注意是下面那个添加配置代码 log-binmysql-bin # 配置二进制日志 server-id1…

豆包新模型矩阵+PromptPilot:AI开发效率革命的终极方案

> **一套让AI开发者告别“调参炼狱”的黄金组合,效率提升300%的实战指南** ## 一、AI开发的范式转移:从通用模型到**场景化矩阵** 2025年,AI应用开发面临核心矛盾:**业务场景高度细分**与**模型能力同质化**的冲突。火山引擎的破局之道是推出**豆包1.6模型矩阵**——三…

瑞利杂波背景下不同环境的虚警概率与目标检测概率仿真

仿真方案&#xff0c;研究在瑞利杂波背景下&#xff0c;均匀环境、多目标环境和杂波墙环境中的虚警概率(Pfa)和目标检测概率(Pd)。 理论基础 瑞利分布 瑞利分布常用于描述雷达杂波的幅度分布&#xff1a; p(x) (x/σ) * exp(-x/(2σ)), x ≥ 0其中σ是尺度参数&#xff0c;决定…

Spring Boot + Tesseract异步处理框架深度解析,OCR发票识别流水线

Spring Boot Tesseract异步处理框架深度解析&#xff0c;OCR发票识别流水线一、系统架构设计1.1 分布式流水线架构1.2 核心组件职责1.3 数据流设计二、Spring Boot异步框架实现2.1 线程池优化配置2.2 异步服务层设计2.3 异步流水线编排三、Tesseract深度优化3.1 发票专用训练模…

Arm Qt编译Qt例程出错 GLES3/gl3.h: No such file or directory

解决方法 PC&#xff1a;Ubuntu22.04.1 QtCreator&#xff1a; 4.11.1 交叉编译环境&#xff1a;YC6254 开发板提供的 5-编译工具链->qt交叉编译工具 在之前博客配置成功的交叉编译环境&#xff0c;编译Qt5.14.8自带部分Example时&#xff0c;出现 GLES3/gl3.h: No such …

HydroOJ:开源在线判题系统的创新与实践

HydroOJ&#xff1a;开源在线判题系统的创新与实践 在数字化与信息化深度融合的今天&#xff0c;编程教育已成为全球教育改革的重要方向&#xff0c;而在线判题系统&#xff08;Online Judge&#xff0c;简称 OJ&#xff09;作为编程学习、算法训练和竞赛组织的核心工具&#…

tcpdump问题记录

问题一: scapy发送vlan报文&#xff0c;tcpdump过滤抓包未抓到包的问题 发包 sendp([Ether(src"11:22:33:44:55:00")/Dot1Q(vlan1001)/IP()/UDP()/"Hello, VLAN!"], iface"ens9")vlan过滤抓包&#xff0c;不OK。 # tcpdump -i ens9 -nnvve -Q ou…