做为开发者,咱们老是会不经意间的遇到一些使人头疼的需求。好比五彩斑斓的黑,根据手机壳变换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...
不少时候遇到的问题,看似有点麻烦,可是只要去仔分析,而后对问题进行拆解,老是能找到比较好的解决方案的。
文章如有不足或有更好建议,欢迎提出,你们一块儿讨论~