服务器之家

服务器之家 > 正文

React+Antd 实现可增删改表格的示例

时间:2022-02-24 16:44     来源/作者:用户320228579782

最近写了一个小东西,模仿自己原先用vue写的项目改成react语法。写了一个可编辑的表格,期间磕磕碰碰的,打算把bug记录下。先把效果图和代码贴上去,主要用的是react+antd

table表格,点击编辑,打开弹窗,弹窗内是tab切换显示不同的form表单+可编辑表格,表格内操作栏"+",表格内新增一行可编辑的数据,编辑,保存,删除这些操作就不细说也不贴效果图了

React+Antd 实现可增删改表格的示例

React+Antd 实现可增删改表格的示例

React+Antd 实现可增删改表格的示例

React+Antd 实现可增删改表格的示例

React+Antd 实现可增删改表格的示例

 

Table/index.js

  1. import React, { useState }from 'react' 
  2. import { Row,Col,Card, Table, Tag, Divider, Modal, Button } from 'antd'
  3. import ModalData from './model' 
  4.  
  5.  
  6. const App = (props) => { 
  7.  console.log(props,'----'
  8.  const [isModalVisible, setIsModalVisible] = useState(false); 
  9.  const columns = [ 
  10.   { 
  11.    title: 'Name'
  12.    dataIndex: 'name'
  13.    key: 'name'
  14.    render: text => <a>{text}</a>, 
  15.   }, 
  16.   { 
  17.    title: 'Age'
  18.    dataIndex: 'age'
  19.    key: 'age'
  20.   }, 
  21.   { 
  22.    title: 'Address'
  23.    dataIndex: 'address'
  24.    key: 'address'
  25.   }, 
  26.   { 
  27.    title: 'Tags'
  28.    key: 'tags'
  29.    dataIndex: 'tags'
  30.    render: tags => ( 
  31.     <label> 
  32.      {tags.map(tag => { 
  33.       let color = tag.length > 5 ? 'geekblue' : 'green'
  34.       if (tag === 'loser') { 
  35.        color = 'volcano'
  36.       } 
  37.       return ( 
  38.        <Tag color={color} key={tag}> 
  39.         {tag.toUpperCase()} 
  40.        </Tag> 
  41.       ); 
  42.      })} 
  43.     </label> 
  44.    ), 
  45.   }, 
  46.   { 
  47.    title: 'Action'
  48.    key: 'action'
  49.    align:'center'
  50.    render: (record) => ( 
  51.     <label> 
  52.      <a onClick={() => showModal(record)}>编辑</a> 
  53.      <Divider type="vertical" /> 
  54.      {/* <Button onClick={()=>showModal(record)} > 删除</Button> */
  55.      <a onClick={()=>showModal(record)} > 删除</a> 
  56.     </label> 
  57.    ), 
  58.   }, 
  59.  ]; 
  60.  const data = [ 
  61.   { 
  62.    key: '1'
  63.    name: 'John Brown'
  64.    age: 32, 
  65.    address: 'New York No. 1 Lake Park'
  66.    tags: ['nice''developer'], 
  67.   }, 
  68.   { 
  69.    key: '2'
  70.    name: 'Jim Green'
  71.    age: 42, 
  72.    address: 'London No. 1 Lake Park'
  73.    tags: ['loser'], 
  74.   }, 
  75.   { 
  76.    key: '3'
  77.    name: 'Joe Black'
  78.    age: 32, 
  79.    address: 'Sidney No. 1 Lake Park'
  80.    tags: ['cool''teacher'], 
  81.   } 
  82.  ]; 
  83.   
  84.  const showModal = (row) => { 
  85.   setIsModalVisible(true); 
  86.  }; 
  87.  const handleCancel = () => { 
  88.   setIsModalVisible(false); 
  89.  } 
  90.  const handleOk = (form={},data) => { 
  91.   setIsModalVisible(false); 
  92.   console.log(form,data,'pp---'
  93.  } 
  94.  
  95.   
  96.  
  97.  return ( 
  98.   <label> 
  99.    <Row gutter={16} className="gutter-row"
  100.     <Col md={24}> 
  101.      <Card title="基本表格+简单弹框" bordered={false}> 
  102.       <Table columns={columns} dataSource={data} /> 
  103.      </Card> 
  104.     </Col> 
  105.    </Row> 
  106.    {isModalVisible && <ModalData close={()=>{ 
  107.     handleCancel() 
  108.    }} saveOk={(form,data)=>{ handleOk(form,data) }}/>} 
  109.    {/* {isModalVisible && <ModalData />} */
  110.   </label> 
  111.  ); 
  112. }; 
  113. const la = '111' 
  114. export default () => ( 
  115.  <App/> 

Table/model/index.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import React from 'react'
import Basic from './modules/base'
import EditTableData from './modules/editTableData'
import { Modal, Tabs, Spin } from "antd";
 
export default class ModalData extends React.Component{
 constructor(){
  super()
  this.state = {
   isModalVisible:true,
   currentTab:'basicColumns',
   tableData:[]
  }
 }
 componentWillMount(){
  this.setState({
   isModalVisible:this.props.isModalVisible
  })
  this.basicColumns = [
   {title:'操作类型',editable:true,dataIndex:'name'},
   {title:'名称',editable:true,dataIndex:'age'},
   {title:'描述',editable:true,dataIndex:'address'}
  ]
  this.associationColumns = [
   {title:'前置操作',editable:true,dataIndex:'name'},
   {title:'关联权限',editable:true,dataIndex:'age'},
   {title:'关联操作',editable:true,dataIndex:'address'}
  ]
  this.dataViewColumns = [
   {title:'字段',editable:true,dataIndex:'name'},
   {title:'描述',editable:true,dataIndex:'address'}
  ]
 }
 componentWillUpdate(){
  console.log(22)
 }
 componentDidMount(){
  console.log(11)
 }
 handleOk = () => {
  // console.log(this.tabData,'this.formRefThree.props')
  const form = this.formRef.props.form;
  form.validateFields((err, fieldsValue) => {
   if (!err) {
    console.log(this.tabData,'pp---00---');
    this.props.saveOk(fieldsValue,this.tabData)
   }
  });
 }
 saveTable(data){
  console.log(data,this.state.currentTab,'data---')
  this.tabData = {
   [this.state.currentTab]:data
  }
 
 }
 changeTab(key){
  console.log(key,'key---')
  this.setState({
   currentTab:key
  })
 }
 render(){
  
  return (
   <Modal
    title="编辑"
    width={650}
    destroyOnClose
    visible
    onOk={ () => this.handleOk() }
    onCancel={ () => this.props.close()}
   >
    <Tabs onChange={(key)=>this.changeTab(key)} >
     <Tabs.TabPane tab="基本信息" key="basicColumns">
      <span>
       <Basic wrappedComponentRef={(form) => this.formRef = form}/>
       <EditTableData basicColumns={this.basicColumns} saveTable={(data)=>this.saveTable(data)}/>
      </span>
     </Tabs.TabPane>
 
     <Tabs.TabPane tab="关联权限" key="associationColumns">
      <EditTableData associationColumns={this.associationColumns} saveTable={(data)=>this.saveTable(data)}/>
     </Tabs.TabPane>
     <Tabs.TabPane tab="数据视图" key="dataViewColumns">
      <EditTableData dataViewColumns={this.dataViewColumns} saveTable={(data)=>this.saveTable(data)}/>
     </Tabs.TabPane>
    </Tabs>
   </Modal>
  )
 }
}

 

Table/model/modules/base.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import React from 'react'
import { Form, Input, Select, Radio } from 'antd';
const { Option } = Select;
 
// const Basic = (props) => {
class Basic extends React.Component{
 formRef = React.createRef();
 // const [form] = Form.useForm();
 onGenderChange(value){
  switch (value) {
   case 'male':
    this.props.form.setFieldsValue({
     note: 'Hi, man!',
    });
    return;
 
   case 'female':
    this.props.form.setFieldsValue({
     note: 'Hi, lady!',
    });
    return;
 
   case 'other':
    this.props.form.setFieldsValue({
     note: 'Hi there!',
    });
    return;
  }
 }
 onFinish(values){
  console.log(values);
  console.log(this.props.form.getFieldsValue,'09900--')
 }
 
 render(){
  console.log(this.props.form.getFieldValue('gender'),'990----')
  const { form } = this.props;
  const { getFieldDecorator, getFieldValue} = form;
  return (
   <div>
    <Form ref={this.formRef} layout="inline" name="control-hooks" onFinish={this.onFinish.bind(this)}>
     <Form.Item label="权限标识" required>
      {getFieldDecorator("note")(<Input placeholder="请输入"/>)}
     </Form.Item>
     <Form.Item label="权限名称" required>
     {getFieldDecorator("name")(<Input placeholder="请输入"/>)}
     </Form.Item>
     <Form.Item label="requiredMark" name="状态" required>
      {getFieldDecorator("requiredMark")(
       <Radio.Group>
        <Radio.Button value="optional">启用</Radio.Button>
        <Radio.Button value="disabled">禁用</Radio.Button>
       </Radio.Group>
      )}
     </Form.Item>
     <Form.Item name="gender" label="分类" required>
      {getFieldDecorator("gender")(
       <Select style={{width: '250px'}} placeholder="请选择" onChange={this.onGenderChange.bind(this)} allowClear >
        <Option value="male">api借口</Option>
        <Option value="female">租户</Option>
        <Option value="other">系统</Option>
       </Select>
      )}
     </Form.Item>
     {getFieldValue('gender') == 'other' && <Form.Item name="customizeGender" label="备注">
      {getFieldDecorator("customizeGender")(<Input />)}
     </Form.Item>}
    </Form>
   </div>
 
  )
 }
}
export default Form.create()(Basic)

 

Table/model/modules/editTable.js

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import React, { useState } from 'react';
import { Table, Input, InputNumber,Divider, Popconfirm, Form, Typography } from 'antd';
import {PlusSquareOutlined} from '@ant-design/icons';
const { Provider, Consumer } = React.createContext()//组件之间传值
const originData = [];
 
for (let i = 0; i < 5; i++) {
 originData.push({
  key: i.toString(),
  name: `Edrward ${i}`,
  age: 32,
  address: `London Park no. ${i}`,
 });
}
class EditableCell extends React.Component{
 renderCell = ({getFieldDecorator}) => {
  const {
   editing, dataIndex, title, Inputs, record, index, children, ...restProps
  } = this.props
  return (
   <td {...restProps}>
    {editing ? (
     <Form.Item style={{ margin: 0, }} >
      {getFieldDecorator(dataIndex,{
       rules: [{
       required: true,
       message: '请输入'
      }],
      initialValue: record[dataIndex]
      })(
      <Inputs />
      )}
     </Form.Item>
    ) : (
     children
    )}
   </td>
  );
 }
 render(){
  return <Consumer>{this.renderCell}</Consumer>
 }
}
 
class EditTableData extends React.Component{
 constructor(props){
  super(props)
  this.state = {
   data:originData,
   editingKey:''
  }
 }
 // 判断是否可编辑
 isEditing = record => record.key == this.state.editingKey
 
 // 初始化
 init(){
  console.log(this.props,'pp--')
  const data = this.props.basicColumns || this.props.dataViewColumns || this.props.associationColumns || []
  this.columns = [
   ...data,
   {
    title: ()=>{
     return <span>操作<Divider type="vertical" /><PlusSquareOutlined style={{color:"#333"}} onClick={()=>this.addColumns()}/></span>
    },
    width:'20%',
    dataIndex: 'operation',
    render: (_, record) => {
     const { editingKey } = this.state
     const editable = this.isEditing(record);
     return editable ? (
      <span>
       <Consumer>
        {
         form => (
         <a onClick={() => this.save(form,record.key)} >
          保存
         </a>)
        }
       </Consumer>
       <Divider type="vertical" />
       <Popconfirm okText="确认" cancelText="取消" title="是否确定取消?" onConfirm={this.cancel}>
        <a>取消</a>
       </Popconfirm>
      </span>
     ) : (
       <span>
        <a disabled={editingKey != ''} onClick={()=>this.edit(record.key)}>编辑</a>
        <Divider type="vertical" />
        <Popconfirm okText="确认" cancelText="取消" title="是否确定取消?" onConfirm={()=>this.delete(record.key)}>
         <a>删除</a>
        </Popconfirm>
       </span>
     );
    },
   },
  ];
 }
 // 添加
 addColumns = () => {
  const newData = [...this.state.data]
  newData.push({
   key: newData.length,
   name: ``,
   age: '',
   address: ``
  })
  this.setState({
   data:newData
  })
 }
 // 编辑
 edit = (key) => {
  this.setState({
   editingKey:key
  })
 }
 // 删除
 delete = (key) => {
  const newData = [...this.state.data]
  const index = newData.findIndex(item=>item.key == key)
  newData.splice(index,1)
  this.setState({
   data:newData
  })
 }
 // 保存
 save = (form,key) => {
  form.validateFields((error,row)=>{
   if(error){
    return
   }
   const newData = [...this.state.data]
   const index = newData.findIndex(item=>item.key == key)
   if(index > -1){
    const item = newData[index]
    newData.splice(index,1,{
     ...item,...row
    })
   }
   this.setState({
    editingKey:'',
    data:newData
   })
   this.props.saveTable(newData)
  })
 
 }
 
 // 取消
 cancel = () => {
  this.setState({
   editingKey: ''
  })
 }
 
 render(){
  this.init()
  console.log(this.columns,'columns')
  const columns = this.columns.map(col => {
   if(!col.editable){
    return col
   }
   return {
    ...col,
    onCell:record => ({
     record,
     Inputs:Input,
     dataIndex:col.dataIndex,
     title:col.title,
     editing:this.isEditing(record)
    })
   }
  })
  return (
   <Provider value={this.props.form}>
    <Table bordered style={{marginTop:'30px'}} components={{
     body:{
      cell:EditableCell
     }
    }} columns={columns} dataSource={this.state.data} pagination={false}/>
   </Provider>
  )
 }
}
 
 
export default Form.create()(EditTableData)

以上就是React+Antd实现可增删改表格的示例的详细内容,更多关于React+Antd实现可增删改表格的资料请关注服务器之家其它相关文章!

原文链接:https://juejin.cn/post/6947969446501679117

标签:

相关文章

热门资讯

蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整
蜘蛛侠3英雄无归3正片免费播放 蜘蛛侠3在线观看免费高清完整 2021-08-24
2022年最旺的微信头像大全 微信头像2022年最新版图片
2022年最旺的微信头像大全 微信头像2022年最新版图片 2022-01-10
背刺什么意思 网络词语背刺是什么梗
背刺什么意思 网络词语背刺是什么梗 2020-05-22
yue是什么意思 网络流行语yue了是什么梗
yue是什么意思 网络流行语yue了是什么梗 2020-10-11
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全
2020微信伤感网名听哭了 让对方看到心疼的伤感网名大全 2019-12-26
返回顶部