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

news2024/11/19 0:29:27

前言

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] = value
    this.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>
          <Select
            defaultValue={this.state.searchForm.selectValue}
            style={this.searchDom}
            allowClear
            options={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] = rowData
        this.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)
                break
            default:
                this.setFormValue(e.target.value, name)
        }
    }
    setFormValue = (value, key, fn) => {
        let _formData = this.state.formData
        _formData[key] = value
        this.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>
                <Form
                    ref={this.formRef}
                    name="validate_other"
                    {...formItemLayout}
                    onFinish={onFinish}
                    initialValues={this.state.formData}
                    style={{
                        maxWidth: 600,
                    }}
                >
                    <Form.Item
                        name="name"
                        label="姓名"
                        hasFeedback
                        rules={[
                            {
                                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="描述">
                        <TextArea
                            showCount
                            maxLength={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

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

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

相关文章

什么是同步通信?什么是异步通信?两者的优缺点是什么?

什么是通信&#xff1f; 通信是指人与人或人与自然之间通过某种行为或媒介进行的信息交流与传递。从广义上来说&#xff0c;通信是指需要信息的双方或多方在不违背各自意愿的情况下采用任意方法、任意媒质&#xff0c;将信息从某方准确安全地传送到另方。在出现电波传递通信…

Element-UI el-row 排版样式错乱

Element-UI el-row el-col 配合el-form 表单使用&#xff0c;造成样式的错乱。 如图&#xff1a; ![在这里插入图片描述](https://img-blog.csdnimg.cn/13520a35e3d44e4099b5bc04d5201f29.png#pic_center 大概就是这个&#xff0c;代码&#xff1a; <el-row gutter"…

coturn服务器的搭建

Window下搭建coturn服务器&#xff1a; 准备材料&#xff1a; 1、安装Cygwin&#xff0c;地址&#xff1a;https://cygwin.com/install.html 由于Window无法直接部署coturn&#xff0c;因此需要下载安装Cygwin在Window上部署Linux虚拟环境。 在安装的时候需要安装几下packe…

vue实现记事本(无样式版)

实现了增、删功能&#xff0c;任务统计&#xff0c;全删除功能。 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0">…

【达梦数据库】DM概述、数据定义(表空间管理、用户管理、模式管理、表管理)

文章目录 DM概述数据定义表空间管理1. 创建表空间2. 修改表空间3. 删除表空间 用户管理1. 创建用户2. 修改用户3. 删除用户 模式管理1. 创建模式(2种方法)2. 设置当前模式3. 删除模式 表管理1. 创建表2. 修改表3. 删除表 文章有点点长&#xff0c;可以先收藏哦&#xff0c;如果…

ECCV 22丨BUTD-DETR:图像和点云的语言标定Transformer

来源&#xff1a;投稿 作者&#xff1a;橡皮 编辑&#xff1a;学姐 论文链接&#xff1a;https://arxiv.org/abs/2112.08879[1] 主页链接&#xff1a;https://github.com/nickgkan/butd\_detr[2] 摘要&#xff1a; 在二维和三维场景中&#xff0c;大多数模型的任务都是将指涉…

Kafka生产问题总结及性能优化实践

Kafka可视化管理工具kafka-manager 安装及基本使用可参考&#xff1a;https://www.cnblogs.com/dadonggg/p/8205302.html 线上环境规划 JVM参数设置 kafka是scala语言开发&#xff0c;运行在JVM上&#xff0c;需要对JVM参数合理设置&#xff0c;参看JVM调优专题 修改bin/kaf…

算法通关村第十二关黄金挑战——最长公共前缀问题解析

大家好&#xff0c;我是怒码少年小码。 最长公共前缀 LeetCode 14&#xff1a;编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 示例&#xff1a; 输入&#xff1a;strs [“flower”,“flow”,“flight”]输出&#xff…

CSS+Javascript+Html日历控件

最近&#xff0c;因需要用HTMLJAVASCRIPTCSS实现了一个日历控件&#xff0c;效果如下&#xff1a; 单击上月、下月进行日历切换。当前日期在日历中变颜色标注显示。还是老老套路、老方法&#xff0c;分HMLCSSJAVASCRIPT三部分代码。 一、html代码 <h1>学习计划</h1…

HubSpot CRM是什么?如何添加、使用呢?

HubSpot CRM是一款强大的客户关系管理工具&#xff0c;它不仅简化了销售和市场营销过程&#xff0c;还提供了多种功能&#xff0c;有助于增强客户互动、提高销售效率和提供更多的洞察信息。 今天运营坛将带领大家深入了解HubSpot CRM&#xff0c;涵盖了它的定义、使用流程、添…

国产芯片vs“国际水平”,有距离也有超越!

当前&#xff0c;国产芯片正在迎来全新的发展阶段。国产终端芯片性能怎么样&#xff0c;与国际主流产品相比&#xff0c;表现如何&#xff1f;今天笔者就针对目前热度较高的四款国产CPU进行参数分析与性能跑分横向对比。 此次国产芯片评测型号分别是海光C86-3250、龙芯3A5000H…

java蓝桥11-20题总结

文章目录 11.排序1.代码2.知识点冒泡排序 12.跑步锻炼1.代码 13.蛇形填数1.代码 14.递增序列1.代码 15.AB&#xff08;OJ示例题目&#xff09;16.杨辉三角形1.代码2.知识点 17.货物1.代码 18.九进制转十进制1.代码 19.等差素数列1.代码 20.七段码 11.排序 1.代码 package lanq…

网络套接字编程(一)

网络套接字编程(一) 文章目录 网络套接字编程(一)预备知识源IP地址和目的IP地址端口号TCP/UDP协议特点网络字节序 socket编程socket常用APIsockaddr结构 简易UDP网络程序服务端创建套接字服务端绑定IP地址和端口号字符型IP地址VS整型IP地址服务端运行客户端创建套接字客户端绑定…

python使用ffmpeg来制作音频格式转换工具(优化版)

简介:一个使用python加上ffmpeg模块来进行音频格式转换的工具。 日志: 20231030:第一版,设置了简单的UI布局和配色,实现音频转为Mp3、AAC、wav、flac四种格式。可解析音频并显示信息,可设置转换后的保存路径 UI界面: 编程平台:visual studio code 编程语言:python 3…

如何把编辑器编辑好的文章分享给别人?

哈喽&#xff0c;大家好&#xff0c;今天小编给大家分享一个非常实用的功能&#xff0c;当我们在使用微信编辑器编辑排版文章的时候&#xff0c;需要在不发表的前提下分享给好友或者需要先给领导看一下的时候该怎么办呢&#xff1f;有三个方法&#xff0c;都可以在不发表的前提…

Ortec974A EPICS IOC程序

1&#xff09; 创建一个用户存放这个IOC程序结构的目录&#xff1a; rootorangepi4-lts:/usr/local/EPICS/program# mkdir ortec974A rootorangepi4-lts:/usr/local/EPICS/program# cd ortec974A/ rootorangepi4-lts:/usr/local/EPICS/program/ortec974A# ls2&#xff09;使用…

系列四十二、Spring的事务传播行为案例演示(二)#REQUIRED

一、演示Spring的默认传播行为&#xff08;REQUIRED&#xff09; 1.1、运行之前表中的数据 1.2、StockServiceImpl /*** Author : 一叶浮萍归大海* Date: 2023/10/30 15:43* Description:*/ Service(value "stockServiceREQUIRED") public class StockServiceImpl…

Mysql设置了更新时间自动更新,指定更新部分sql时不进行时间更新

现象&#xff1a; 因为字段设置了自动更新&#xff0c;所以sql语句一进行修改此字段就会自动更新时间&#xff0c;但是呢我们的有部分定时任务是半夜执行&#xff0c;并且不能让这个任务修改到数据的更新时间 解决&#xff1a; <update id"updateCreative">ALT…

element-plus DateTimePicker日期选择器,限制指定日期和时间不可选择

element-plus日期选择器&#xff0c;在指定日期时间前不可选择。 限制日期选择&#xff0c;使用disabled-date 限制小时选择&#xff0c;使用disabled-hours 限制分钟选择&#xff0c;使用disabled-minutes 限制毫秒选择&#xff0c;使用disabled-seconds 指定日期当天的时间有…

一带一路10周年:爱创科技加速中国药企国际化征程

“源自中国&#xff0c;属于世界”。 共建“一带一路”倡议提出10周年来&#xff0c;中国与沿线国家经济深度融合&#xff0c;在共商共建共享的基本原则下&#xff0c;“一带一路”形成了国际合作的平台和机制&#xff0c;跨国经济合作已基本形成。 随着“一带一路”合作日益加…