React+Antd 實(shí)現(xiàn)可增刪改表格的示例
最近寫了一個(gè)小東西,模仿自己原先用vue寫的項(xiàng)目改成react語(yǔ)法。寫了一個(gè)可編輯的表格,期間磕磕碰碰的,打算把bug記錄下。先把效果圖和代碼貼上去,主要用的是react+antd
table表格,點(diǎn)擊編輯,打開彈窗,彈窗內(nèi)是tab切換顯示不同的form表單+可編輯表格,表格內(nèi)操作欄"+",表格內(nèi)新增一行可編輯的數(shù)據(jù),編輯,保存,刪除這些操作就不細(xì)說(shuō)也不貼效果圖了
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="基本表格+簡(jiǎn)單彈框" 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
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:'關(guān)聯(lián)權(quán)限',editable:true,dataIndex:'age'}, {title:'關(guān)聯(lián)操作',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="關(guān)聯(lián)權(quán)限" key="associationColumns"> <EditTableData associationColumns={this.associationColumns} saveTable={(data)=>this.saveTable(data)}/> </Tabs.TabPane> <Tabs.TabPane tab="數(shù)據(jù)視圖" key="dataViewColumns"> <EditTableData dataViewColumns={this.dataViewColumns} saveTable={(data)=>this.saveTable(data)}/> </Tabs.TabPane> </Tabs> </Modal> ) } }
Table/model/modules/base.js
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="權(quán)限標(biāo)識(shí)" required> {getFieldDecorator("note")(<Input placeholder="請(qǐng)輸入"/>)} </Form.Item> <Form.Item label="權(quán)限名稱" required> {getFieldDecorator("name")(<Input placeholder="請(qǐng)輸入"/>)} </Form.Item> <Form.Item label="requiredMark" name="狀態(tài)" 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="請(qǐng)選擇" onChange={this.onGenderChange.bind(this)} allowClear > <Option value="male">api借口</Option> <Option value="female">租戶</Option> <Option value="other">系統(tǒng)</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
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: '請(qǐng)輸入' }], 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="確認(rèn)" cancelText="取消" title="是否確定取消?" onConfirm={this.cancel}> <a>取消</a> </Popconfirm> </span> ) : ( <span> <a disabled={editingKey != ''} onClick={()=>this.edit(record.key)}>編輯</a> <Divider type="vertical" /> <Popconfirm okText="確認(rèn)" 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實(shí)現(xiàn)可增刪改表格的示例的詳細(xì)內(nèi)容,更多關(guān)于React+Antd實(shí)現(xiàn)可增刪改表格的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React18系列commit從0實(shí)現(xiàn)源碼解析
這篇文章主要為大家介紹了React18系列commit從0實(shí)現(xiàn)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01Remix 后臺(tái)桌面開發(fā)electron-remix-antd-admin
這篇文章主要為大家介紹了Remix 后臺(tái)桌面開發(fā)electron-remix-antd-admin的過(guò)程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04React中實(shí)現(xiàn)keepalive組件緩存效果的方法詳解
由于react官方并沒(méi)有提供緩存組件相關(guān)的api(類似vue中的keepalive),在某些場(chǎng)景,會(huì)使得頁(yè)面交互性變的很差。所以本文為大家介紹了React中實(shí)現(xiàn)keepalive組件緩存效果的方法,希望對(duì)大家有所幫助2023-01-01詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟
本篇文章主要介紹了詳解Webpack+Babel+React開發(fā)環(huán)境的搭建的方法步驟,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01react源碼中的生命周期和事件系統(tǒng)實(shí)例解析
這篇文章主要為大家介紹了react源碼中的生命周期和事件系統(tǒng)實(shí)例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01react組件中過(guò)渡動(dòng)畫的問(wèn)題解決
這篇文章主要為大家介紹了react組件中過(guò)渡動(dòng)畫的問(wèn)題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09React onBlur回調(diào)中使用document.activeElement返回body完美解決方案
這篇文章主要介紹了React onBlur回調(diào)中使用document.activeElement返回body完美解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04React中useEffect 與 useLayoutEffect的區(qū)別
本文主要介紹了React中useEffect與useLayoutEffect的區(qū)別,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07