做爲開發者,咱們老是會不經意間的遇到一些使人頭疼的需求。好比五彩斑斕的黑,根據手機殼變換APP的顏色等等,你說怎麼辦。雖然在通常狀況下不會這麼棘手,可是有些需求剛拿到的時候仍是會束手無策。javascript
曾經遇到一個相似這樣的需求:A表的數據須要沿用B表中的數據,並且要儘可能少的步驟。具體什麼意思呢,意思就是完成一個相似於下面這種效果:
html
這個該這麼搞,直接給產品說,對不起實現不了。html5
但是產品卻告訴我,不行不行,必須實現。java
沒辦法,只好妥協。react
OK,咱們來理理思路,首先肯定一下現有的主要開發環境:antd
既然要實現上圖所示的拖放效果,那麼HTML5的拖放一系列API(Drag 和 Drop等)確定就是主角了。原生API以及用法能夠點擊這裏進行摸索。框架
熟悉了API後咱們便要對需求進行分析,明確三個要點:第一是拖放的動做,這個用拖放API就能很好的解決;第二是表格間的數據交互,也就是怎麼把表格B中部分數據(序號)添加到表格A(沿用信息);第三是表格B中每一行的序號與表格A中的沿用信息都是一對多的關係,並且表格A中的沿用信息是便可添加也能夠替換的。this
弄清楚須要解決的要點後,咱們就能夠着手coding了。spa
首先,咱們要先創建兩張表格,而且製造假數據:code
import React, { Component } from 'react'; import {Table, Row, Col, Button} from 'antd'; export class App extends Component { columnsA columnsB constructor(props) { super(props); this.columnA = [ { title: '姓名', dataIndex: 'name', key: 'name', }, { width: 100, title: '沿用信息', dataIndex: 'obj', key: 'obj', } ] this.columnsB = [ { title: '序號', dataIndex: 'num', key: 'num', }, { title: '信息', dataIndex: 'info', key: 'info', } ] this.state = { dataSourceA: [ { key: '1', name: '小明', obj: '' }, { key: '2', name: '李華', obj: '' }, { key: '3', name: '小花', obj: '' } ], dataSourceB: [ { key: '1', num: '1', info: '信息一' }, { key: '2', num: '2', info: '信息一' }, { key: '3', num: '3', info: '信息一' } ] } } componentDidMount(){ } render(){ return ( <div className="content" style={{margin: "20px 20px"}}> <Row gutter={24}> <Col span={11}> <Table columns={this.columnsA} dataSource={this.state.dataSourceA} /> </Col> <Col span={11}> <Table columns={this.columnsB} dataSource={this.state.dataSourceB} /> </Col> </Row> </div> ) } }
效果以下:
接下來就是實現拖放動做,由於這裏使用了antd的Table組件,因此咱們很天然的就能夠想到在columns作文章,在這裏把原生的拖放API進行拓展。序號是須要拖拽的元素,而沿用信息是須要進行接收的元素。爲了讓拖放更加明顯,因此咱們在這裏也加了一點樣式:
this.columnA = [ { title: '姓名', dataIndex: 'name', key: 'name', }, { width: 100, title: '沿用信息', dataIndex: 'obj', key: 'obj', render: (value, row, index) => { return <div id={'drop'+index} style={{height:"30px",width:"30px",border:"1px solid #eee",textAlign: "center",lineHeight: "30px"}} onDrop={(e) => { e.preventDefault(); this.drop(e) }} onDragOver={this.allowDrop} >{value}</div> } } ] this.columnsB = [ { title: '序號', dataIndex: 'num', key: 'num', render: (value, row, index) => { return <div draggable="true" id={'drag'+value} style={{height:"30px",width:"30px",border:"1px solid #eee",textAlign: "center",lineHeight: "30px"}} onDragStart={(e) => { this.drag(e) }}>{value}</div> } }, { title: '信息', dataIndex: 'info', key: 'info', } ]
drag = (e) => { console.log(e) }; drop = (e) => { console.log(e); }; allowDrop = (e) => { e.preventDefault(); };
效果以下:
拖放動做是有了,可是兩個表格的數據並無發生變化,因此接下來咱們要進行數據的處理。想要進行數據的傳遞,咱們能夠利用拖放API中的:
// columnsA { width: 100, title: '沿用信息', dataIndex: 'obj', key: 'obj', render: (value, row, index) => { return <div id={'drop'+index} style={{height:"30px",width:"30px",border:"1px solid #eee",textAlign: "center",lineHeight: "30px"}} onDrop={(e) => { e.preventDefault(); this.drop(e) }} onDragOver={this.allowDrop} >{value}</div> } } // columnsB { title: '序號', dataIndex: 'num', key: 'num', render: (value, row, index) => { return <div draggable="true" id={'drag'+value} style={{height:"30px",width:"30px",border:"1px solid #eee",textAlign: "center",lineHeight: "30px"}} onDragStart={(e) => { this.drag(e,value) }}>{value}</div> } },
drag = (e,value) => { console.log(e) e.dataTransfer.setData('value', value) }; drop = (e, key) => { let value = e.dataTransfer.getData('value') console.log("獲取數據:",value); };
能夠看到,咱們已經可以獲取到拖拽的數據了。最後咱們要對錶格A的數據進行處理,首先對dataSourceA進行遍歷,若是其中的元素的key和接受數據的元素的key相等的話,那就對此元素的obj字段進行賦值:
// columnsA { width: 100, title: '沿用信息', dataIndex: 'obj', key: 'obj', render: (value, row, index) => { return <div id={'drop'+index} style={{height:"30px",width:"30px",border:"1px solid #eee",textAlign: "center",lineHeight: "30px"}} onDrop={(e) => { e.preventDefault(); this.drop(e, row.key) }} onDragOver={this.allowDrop} >{value}</div> } }
drop = (e, key) => { let value = e.dataTransfer.getData('value') console.log("獲取數據:",value); let data = this.state.dataSourceA; data.forEach((item) => { if (item.key == key) { item.obj = value } }); this.setState({ dataSourceA: data }) };
看看效果:
固然咱們也能夠把表格A中的數據打印出來看看:
數據真實的發生了改變~~
這個demo基本就算完成了,以上代碼結合起來差很少就是這次demo的完整代碼。
https://www.runoob.com/html/h...
https://developer.mozilla.org...
不少時候遇到的問題,看似有點麻煩,可是隻要去仔分析,而後對問題進行拆解,老是能找到比較好的解決方案的。
文章如有不足或有更好建議,歡迎提出,你們一塊兒討論~