当前位置: 首页 > news >正文

react实现列表增删改查的小demo(class组件版)

前言

react的语法上就是比vue麻烦不少,既然要开手动挡,那就开吧,一个基础的demo

效果图

列表

新增弹窗

编辑弹框

 新增一条数据后的效果

代码

根组件  index.jsx

import React, { Component,createRef} from 'react'
import withRouter from '../../utils/withRouter'
import GlobalFormCom from './globalForm'
import GlobalTable from './globalTable'
import './index.less'
import { cloneDeep } from 'lodash'
import { Input, Select , Button , Modal } from 'antd';
import PubSub from 'pubsub-js'export default withRouter(class index extends Component {state = {searchForm:{searchName:'王惊涛',selectValue:'jsCoder'},modalInfo:{isModalOpen:false,modalTitle:'新建数据',},doneType:'add',addFormData:{},editFormData:{},editRecord:{}}searchDom = {width: '200px',marginRight:'16px'}selectOptions = [{label:'前端',value:'jsCoder'},{label:'后端',value:'pythonCoder'}]changeNameInput = (e,name) => {this.setValue('searchForm',this.state.searchForm,name,e.target.value)}changeSelectValue = (e,name) =>{this.setValue('searchForm',this.state.searchForm,name,e)}setValue = (name,data,key,value,fn)=>{let _data = cloneDeep(data)_data[key] = valuethis.setState({[name]:_data},()=>{if(fn){fn()}})}openModal = (flag) =>{this.setState({doneType:flag})let fn = ()=>{this.setValue('modalInfo',this.state.modalInfo,'modalTitle','新建数据')}this.setValue('modalInfo',this.state.modalInfo,'isModalOpen',true,fn)}editHandler = (editData)=>{this.setState({doneType:'edit'},()=>{this.setValue('modalInfo',this.state.modalInfo,'modalTitle','编辑数据')})let data = cloneDeep(editData)this.setState({editRecord:data})this.setValue('modalInfo',this.state.modalInfo,'isModalOpen',true,()=>{setTimeout(()=>{PubSub.publish('editForm',this.state.editRecord)})})}handleOk = ()=>{// this.handleCancel()if(this.state.doneType === 'add'){PubSub.publish('getFormData','add')}else if(this.state.doneType === 'edit'){PubSub.publish('getFormData','edit')}}handleCancel = ()=>{let fn = ()=>{}this.setValue('modalInfo',this.state.modalInfo,'isModalOpen',false,fn)}globalFormStyle = ()=>{if(this.state.isModalOpen === false){return {display:none}}}sendFormData = (formData,flag)=>{if(flag === 'add'){this.setState({addFormData:formData},()=>{PubSub.publish('addTableData',this.state.addFormData)})}else if(flag === 'edit'){this.setState({editFormData:formData},()=>{PubSub.publish('editTableData',this.state.editFormData)})}}reqList = ()=>{setTimeout(()=>{PubSub.publish('reqList')})}render() {return (<div className='content'><div className='topSearch'><span className='labelSpan'>姓名:</span><Input placeholder="输入姓名" onChange={(e)=>this.changeNameInput(e,'searchName')} value={this.state.searchForm.searchName} style={this.searchDom} /><span className='labelSpan'>类型:</span><SelectdefaultValue={this.state.searchForm.selectValue}style={this.searchDom}allowClearoptions={this.selectOptions}onChange={(e)=>this.changeSelectValue(e,'selectValue')}/><Button type='primary' onClick={this.reqList}>数据重置</Button><Button type='primary' className='addBtn' onClick={()=>this.openModal('add')}>新增</Button></div><div className='tableBox'><GlobalTable addFormData={this.state.addFormData}  closeModal={this.handleCancel} editHandler={this.editHandler}></GlobalTable></div><div className='footer'></div><Modal title={this.state.modalInfo.modalTitle} open={this.state.modalInfo.isModalOpen} onOk={this.handleOk} onCancel={this.handleCancel} width="800px" okText="确定" cancelText="取消" destroyOnClose><GlobalFormCom sendFormData={this.sendFormData}></GlobalFormCom></Modal></div>)}
})

表格组件 globalTable.jsx

import React, { Component } from 'react'
import withRouter from '../../utils/withRouter'
import { Table, Tag, Space, Button } from 'antd';
const { Column, ColumnGroup } = Table;
import PubSub from 'pubsub-js';
import { cloneDeep } from 'lodash';
export default withRouter(class globalTable extends Component {state = {data: []}genderMap = {man: '男',woman: '女'}workMap = {pythonCoder: '后端',jsCoder: '前端'}componentDidMount() {this.reqList()PubSub.unsubscribe('addTableData')PubSub.subscribe('addTableData',(msg,data)=>{this.setTableHandler(data,'add')})PubSub.unsubscribe('editTableData')PubSub.subscribe('editTableData',(msg,data)=>{this.changeTableRow(data)})PubSub.unsubscribe('reqList')PubSub.subscribe('reqList',()=>{this.reqList()})}changeTableRow = (rowData)=>{let cloneTableData = cloneDeep(this.state.data)let index = cloneTableData.findIndex(val=>val.name === rowData.name)cloneTableData[index] = rowDatathis.setState({data:cloneTableData})this.props['closeModal']()}setTableHandler = (data,type)=>{let tableData = cloneDeep(this.state.data)if(type === 'add'){tableData.push(data)this.setState({data:tableData},()=>{this.props['closeModal']()})}}actionBtn = {marginRight:'12px'}editHandler =(record)=>{this.props.editHandler(record)}deleteHandler = (record)=>{let index = this.state.data.findIndex(item=>item.name === record.name)if(index !== -1){let tableData = cloneDeep(this.state.data)tableData.splice(index,1)this.setState({data:tableData})}}reqList = ()=>{this.setState({data:[{name: '马师',gender: 'woman',work: 'jsCoder',birthDate: '1995-01-04',desc: '描述文字'}]})}render() {return (<div><Table dataSource={this.state.data} rowKey="name" pagination={false}><Column title="姓名" dataIndex="name" key="name" width={120}></Column><Column title="性别" dataIndex="gender" key="gender" width={80} render={(text, record) => {return <span>{this.genderMap[text]}</span>}}></Column><Column title="工作" dataIndex="work" key="work" width={200} render={(text => (<span>{this.workMap[text]}</span>))}></Column><Column title="出生日期" dataIndex="birthDate" key="birthDate" width={200}></Column><Column title="描述" dataIndex="desc" key="desc"></Column><Column title="操作" key="action" width={280} render={(text,record) => (<div><Button type='primary' style={this.actionBtn} onClick={()=>this.editHandler(record)} >编辑</Button><Button style={this.actionBtn} onClick={()=>this.deleteHandler(record)}>删除</Button></div>)}></Column></Table></div>)}
})

 表单组件 globalForm.jsx

import React, { Component, forwardRef, createRef } from 'react'
import withRouter from '../../utils/withRouter'
import { InboxOutlined, UploadOutlined } from '@ant-design/icons';
import PubSub from 'pubsub-js';
import {Input,Form,Radio,Select,DatePicker
} from 'antd';
import dayjs from 'dayjs';
const { Option } = Select;
const { TextArea } = Input;
const formItemLayout = {labelCol: {span: 6,},wrapperCol: {span: 14,},
};
const normFile = (e) => {if (Array.isArray(e)) {return e;}return e?.fileList;
};
const onFinish = (values) => {
};const GlobalForm = withRouter(class index extends Component {state = {formData: {name: '',gender: true,work: null,desc: '',birthDate: null,}}workList = [{label: '前端',value: 'jsCoder'},{label: '后端',value: 'pythonCoder'}]changeFormItem = (e, name) => {switch (name) {case 'work':this.setFormValue(e, name)case 'birthDate':this.setFormValue(e, name)breakdefault:this.setFormValue(e.target.value, name)}}setFormValue = (value, key, fn) => {let _formData = this.state.formData_formData[key] = valuethis.setState({ formData: _formData }, () => {if (fn) {fn()}})}changeDate = (date, dateString) => {this.setFormValue(dateString, 'birthDate')}componentDidMount() {PubSub.unsubscribe('getFormData')PubSub.subscribe('getFormData', (msg, data) => {if (data === 'add') {this.formRef.current.validateFields().then((value) => {this.props.sendFormData(this.state.formData, 'add')}).catch((error) => {})} else if (data === 'edit') {this.formRef.current.validateFields().then((value) => {this.props.sendFormData(this.state.formData, 'edit')}).catch((error) => {})}})PubSub.unsubscribe('editForm')PubSub.subscribe('editForm', (msg, data) => {data.birthDate = dayjs(data.birthDate)this.setState({ formData: data }, () => {for (let item in data) {this.formRef.current.setFieldValue(item, data[item])}})})}componentDidUpdate() {}componentWillUnmount() {PubSub.unsubscribe('getFormData')PubSub.unsubscribe('editForm')}formRef = createRef()render() {return (<div><Formref={this.formRef}name="validate_other"{...formItemLayout}onFinish={onFinish}initialValues={this.state.formData}style={{maxWidth: 600,}}><Form.Itemname="name"label="姓名"hasFeedbackrules={[{required: true,message: '请输入名字',},]}><Input placeholder="请输入姓名" onChange={(e) => this.changeFormItem(e, 'name')} value={this.state.formData.name}></Input></Form.Item><Form.Item name="gender" label="性别" rules={[{required: true,message: '请选择性别',},]}><Radio.Group value={this.state.formData.gender} onChange={(e) => this.changeFormItem(e, 'gender')}><Radio value="man">男</Radio><Radio value="woman">女</Radio></Radio.Group></Form.Item><Form.Item name="work" label="工作" rules={[{required: true,message: '请选择工作',},]}><Select value={this.state.formData.work} onChange={(e) => this.changeFormItem(e, 'work')} options={this.workList}></Select></Form.Item><Form.Item name="birthDate" label="出生日期" rules={[{required: true,message: '请选择出生日期',},]}><DatePicker showTime onChange={(date, dateString) => this.changeDate(date, dateString)} defaultValue={dayjs(this.state.formData.birthDate, 'YYYY/MM/DD')} format='YYYY/MM/DD' /></Form.Item><Form.Item name="desc" label="描述"><TextAreashowCountmaxLength={100}style={{height: 120,marginBottom: 24,}}value={this.state.formData.desc}onChange={(e) => this.changeFormItem(e, 'desc')}placeholder="请输入描述内容"/></Form.Item></Form></div>)}
})export default forwardRef((props, ref) => {return <GlobalForm {...props} forwardRef={ref}></GlobalForm>
})

公共外套组件 withRouter.jsx

import {useLocation,useNavigate,useParams,} from "react-router-dom";function withRouter(Component) {function ComponentWithRouterProp(props) {let location = useLocation();let navigate = useNavigate();let params = useParams();return (<Component{...props}router={{ location, navigate, params }}/>);}return ComponentWithRouterProp;}export default withRouter

相关文章:

react实现列表增删改查的小demo(class组件版)

前言 react的语法上就是比vue麻烦不少,既然要开手动挡,那就开吧,一个基础的demo 效果图 列表 新增弹窗 编辑弹框 新增一条数据后的效果 代码 根组件 index.jsx import React, { Component,createRef} from react import withRouter from ../../utils/withRouter import G…...

运行批处理文件,Windows 10至少提供了三种方法,有的可以设置定时运行

Windows 10至少有三种写入批处理文件的方法。你可以使用命令提示符或文件资源管理器按需运行它们。你可以使用任务计划程序配置脚本,以便按计划运行。或者,你可以将批处理文件保存在“启动”文件夹中,让系统在你登录帐户后立即运行它们。 如果要按需运行脚本,可以使用文件…...

C++ detach线程的归属权和控制权交给runtime library的原因

在C中&#xff0c;std::thread的detach操作将线程的归属权和控制权都转移给了C运行时库&#xff08;runtime library&#xff09;。这是因为detach操作的目的是告诉C运行时库&#xff0c;你不再关心这个线程的状态&#xff0c;它可以在后台独立运行&#xff0c;而不需要等待主线…...

Android应用集成RabbitMQ消息处理指南

Android应用集成RabbitMQ消息处理指南 RabbitMQ1、前言2、RabbitMQ简介2.1、什么是RabbitMQ2.2、RabbitMQ的特点2.3、RabbitMQ的工作原理2.4、RabbitMQ中几个重要的概念 3、在Android Studio中集成RabbitMQ3.1、在Manifest中添加权限&#xff1a;3.2、在build.gradle(:app)下添…...

爆改86㎡户型,中式禅意,自然诗意!福州中宅装饰,福州装修

自然诗意 中式禅意 东方风韵&#xff0c;涟漪泛晕。 ——致生活感的“空间”&#xff0c;最美的家 案例简介 作品&#xff1a;泛晕 风格&#xff1a;新中式 面积&#xff1a;86平方 楼盘&#xff1a;长乐中南樾府 中国风与现代风混搭 木元素是中国风表达中最具灵魂般的存…...

LVGL库入门 02 - 布局

1、简单布局 可以使用 lv_obj_set_pos(obj, x, y) 调整一个控件的位置&#xff08;或者使用类似的函数单独调整一个方向的坐标&#xff09;&#xff0c;将它放在相对父容器左上角的合适位置。不过这种布局方式非常死板&#xff0c;因为绝对坐标一旦设定就不能自动调整&#xf…...

利用Vue2实现印章徽章组件

需要实现的组件效果&#xff1a; 该组件有设置颜色、大小、旋转度数和文本内容功能。 一、组件实现代码 <template><divclass"first-ring"v-bind"getBindValue":class"getStampBadgeClass":style"{ transform: rotate(${rotate}…...

金麟国际用工-全新蓝领跨境就业服务平台

金麟国际用工-全新蓝领跨境就业服务平台 金麟国际用工平台是一个引领时代的蓝领跨境就业服务平台&#xff0c;专为蓝领求职者和雇主提供一个全面、便捷、高效的就业对接环境。这个平台通过其强大的数字化系统&#xff0c;包括客户管理系统、岗位信息系统和智能营销工具等&…...

性能测试知多少---并发用户

在做性能测试的时候&#xff0c;我们常常听到并发用户、响应时间、吞吐量专业术语&#xff0c;也许大家都理解&#xff0c;这里有一个理解的层次与深度概念。最近有看断念《软件性能详解与案例分析》一书&#xff0c;看了他的讲解&#xff0c;原来我对这些术语的理解还是比较肤…...

自动驾驶算法(三):RRT算法讲解与代码实现(基于采样的路径规划)

目录 1 RRT算法原理 2 RRT算法代码解析 3 RRT完整代码 1 RRT算法原理 RRT算法的全称是快速扩展随机树算法(Rapidly Exploring Random Tree)&#xff0c;它的想法就是从根结点长出一棵树当树枝长到终点的时候这样就能找到从终点到根节点的唯一路径。 算法流程&#xff1a; 首先…...

基于SSM的酒店客房预定管理系统

基于SSM的酒店客房预定管理系统的设计与实现~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringSpringMVCMyBatis工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 前台主页 客房详情 登录界面 管理员界面 用户界面 摘要 基于SSM&#xff08;…...

IDEA初步入门

1 安装 现在的系统更迭很快&#xff0c;很多软件都只支持win10 和 11了&#xff0c;但我们过时党还在用win7. 所以就必须找到合适的版本。在windows 7 64位系统下&#xff0c;可以使用IDEA 2020.1.4版本。 在Jetbrain官方下&#xff0c;找到历史版本&#xff0c;找到windows版…...

《Webpack 5 基础配置》- 禁止在出现编译错误或警告时,覆盖浏览器全屏显示

Webpack5 overlay 配置地址默认编译错误或警告为 true&#xff0c;即浏览器全屏显示&#xff1b;overlay 属性可以是 boolean 型&#xff0c;也可是 object 类型&#xff1b;还有其它设置说明&#xff0c;详见上述官网地址&#xff1b; module.exports {devServer: {client: {…...

echart 饼图怎么让图形铺满整个div

1.原效果&#xff08;未铺满&#xff09;&#xff1a;原配置 2.如果想要铺满&#xff0c;需要设置radius &#xff0c;radius的意思是 第一个元素为内环半径&#xff0c;第二个参数为外环半径&#xff1b; 如果想要填满的话直接写[0,100%],不过第一个为0后就不是圆环里&#…...

回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测

回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测 目录 回归预测 | Matlab实现WOA-CNN-SVM鲸鱼算法优化卷积神经网络-支持向量机的多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.WOA-CNN-SVM鲸鱼算法…...

arm-none-eabi-gcc下实现printf的两种方式

方式1&#xff0c;移植第三方printf库&#xff1a; 1. 下载地址&#xff1a;https://github.com/mpaland/printf 2. 拷贝其中的printf.c和printf.h到本地&#xff1b; 3. 重新实现 void _putchar(char character) 接口&#xff0c;使用具体串口发送ch数据&#xff0c;如在 u…...

组件库开发

组件库开发 环境搭建 menorepo pnpmpnpm-workspacelerna 7.4.2 &#xff08;已全局安装lerna&#xff09; 1、初始化 1.1 新建项目目录root 1.2 在目录root中使用pnpm初始化packages.json文件&#xff0c;新建 pnpm-workspace.yaml文件&#xff0c; packages/文件夹 pnp…...

【python基础】魔法参数*args, **kwargs的使用

文章目录 前言一、*args 和 **kwargs 是什么&#xff1f;二、*args 的用法打包参数&#xff1a;将不定数量的参数传递给一个函数拆分参数&#xff1a;调用一个函数 三、**kwargs 的用法打包参数&#xff1a;将不定数量的参数传递给一个函数拆分参数&#xff1a;调用一个函数 四…...

Android Icon 添加水印 Python脚本

源代码 # -*- coding: utf-8 -*- from PIL import Image 图片合成def mergePictureLXJ():commonIcon Image.open("icon.png")markIcon Image.open("领现金.png")markLayer Image.new(RGBA, commonIcon.size, (0, 0, 0, 0))markLayer.paste(markIcon, (0…...

选择Centos系统需不需要带SElinux?

CentOS 7的SELinux代表"Security-Enhanced Linux"&#xff0c;它是一个Linux操作系统的安全增强功能。SELinux是一个强制访问控制&#xff08;Mandatory Access Control&#xff0c;MAC&#xff09;系统&#xff0c;它在操作系统级别提供了更加精细的访问控制和安全策…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...