最近寫了一個小東西,模仿自己原先用vue寫的項目改成react語法。寫了一個可編輯的表格,期間磕磕碰碰的,打算把bug記錄下。先把效果圖和代碼貼上去,主要用的是react+antd
table表格,點擊編輯,打開彈窗,彈窗內是tab切換顯示不同的form表單+可編輯表格,表格內操作欄"+",表格內新增一行可編輯的數據,編輯,保存,刪除這些操作就不細說也不貼效果圖了
Table/index.js
- import React, { useState }from 'react'
- import { Row,Col,Card, Table, Tag, Divider, Modal, Button } from 'antd';
- import ModalData from './model'
- const App = (props) => {
- console.log(props,'----')
- const [isModalVisible, setIsModalVisible] = useState(false);
- const columns = [
- {
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- render: text => <a>{text}</a>,
- },
- {
- title: 'Age',
- dataIndex: 'age',
- key: 'age',
- },
- {
- title: 'Address',
- dataIndex: 'address',
- key: 'address',
- },
- {
- title: 'Tags',
- key: 'tags',
- dataIndex: 'tags',
- render: tags => (
- <label>
- {tags.map(tag => {
- let color = tag.length > 5 ? 'geekblue' : 'green';
- if (tag === 'loser') {
- color = 'volcano';
- }
- return (
- <Tag color={color} key={tag}>
- {tag.toUpperCase()}
- </Tag>
- );
- })}
- </label>
- ),
- },
- {
- title: 'Action',
- key: 'action',
- align:'center',
- render: (record) => (
- <label>
- <a onClick={() => showModal(record)}>編輯</a>
- <Divider type="vertical" />
- {/* <Button onClick={()=>showModal(record)} > 刪除</Button> */}
- <a onClick={()=>showModal(record)} > 刪除</a>
- </label>
- ),
- },
- ];
- const data = [
- {
- key: '1',
- name: 'John Brown',
- age: 32,
- address: 'New York No. 1 Lake Park',
- tags: ['nice', 'developer'],
- },
- {
- key: '2',
- name: 'Jim Green',
- age: 42,
- address: 'London No. 1 Lake Park',
- tags: ['loser'],
- },
- {
- key: '3',
- name: 'Joe Black',
- age: 32,
- address: 'Sidney No. 1 Lake Park',
- tags: ['cool', 'teacher'],
- }
- ];
- const showModal = (row) => {
- setIsModalVisible(true);
- };
- const handleCancel = () => {
- setIsModalVisible(false);
- }
- const handleOk = (form={},data) => {
- setIsModalVisible(false);
- console.log(form,data,'pp---')
- }
- return (
- <label>
- <Row gutter={16} className="gutter-row">
- <Col md={24}>
- <Card title="基本表格+簡單彈框" bordered={false}>
- <Table columns={columns} dataSource={data} />
- </Card>
- </Col>
- </Row>
- {isModalVisible && <ModalData close={()=>{
- handleCancel()
- }} saveOk={(form,data)=>{ handleOk(form,data) }}/>}
- {/* {isModalVisible && <ModalData />} */}
- </label>
- );
- };
- const la = '111'
- export default () => (
- <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