【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

前言

作为开发者,我们总是会不经意间的遇到一些令人头疼的需求。比如五彩斑斓的黑,根据手机壳变换APP的颜色等等,你说怎么办。虽然在一般情况下不会这么棘手,但是有些需求刚拿到的时候还是会一筹莫展。

表格间数据传递

曾经遇到一个类似这样的需求:A表的数据需要沿用B表中的数据,而且要尽量少的步骤。具体什么意思呢,意思就是完成一个类似于下面这种效果:
【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

这个该这么搞,直接给产品说,对不起实现不了。

可是产品却告诉我,不行不行,必须实现。

没办法,只好妥协。

梳理

OK,我们来理理思路,首先确定一下现有的主要开发环境:

  • 框架:react
  • UI库:antd

既然要实现上图所示的拖放效果,那么HTML5的拖放一系列API(Drag 和 Drop等)肯定就是主角了。原生API以及用法可以点击这里进行摸索。

熟悉了API后我们便要对需求进行分析,明确三个要点:第一是拖放的动作,这个用拖放API就能很好的解决;第二是表格间的数据交互,也就是怎么把表格B中部分数据(序号)添加到表格A(沿用信息);第三是表格B中每一行的序号与表格A中的沿用信息都是一对多的关系,而且表格A中的沿用信息是即可添加也可以替换的。

弄清楚需要解决的要点后,我们就可以着手coding了。

具体实现

首先,我们要先建立两张表格,并且制造假数据:

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>

)

}

}

效果如下:
【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

接下来就是实现拖放动作,因为这里使用了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();

};

效果如下:
【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

拖放动作是有了,但是两个表格的数据并没有发生变化,所以接下来我们要进行数据的处理。想要进行数据的传递,我们可以利用拖放API中的:

  1. dataTransfer.setData()方法设置被拖数据的数据类型和值;
  2. dataTransfer.getData()方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据。

// 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);

};

【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

可以看到,我们已经能够获取到拖拽的数据了。最后我们要对表格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中的数据打印出来看看:
【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互

数据真实的发生了改变~~

这个demo基本就算完成了,以上代码结合起来差不多就是此次demo的完整代码。

参考

https://www.runoob.com/html/h...

https://developer.mozilla.org...

最后

很多时候遇到的问题,看似有点麻烦,但是只要去仔分析,然后对问题进行拆解,总是能找到比较好的解决方案的。

文章若有不足或有更好建议,欢迎提出,大家一起讨论~

以上是 【JS】利用HTML5拖放(Drag 和 Drop)实现Table间数据的交互 的全部内容, 来源链接: utcz.com/a/96586.html

回到顶部