当前位置: 首页 > Web前端 > HTML5

使用HTML5拖放(DragandDrop)实现Table之间的数据交互

时间:2023-04-04 23:38:58 HTML5

前言作为开发者,我们总会在不经意间遇到一些麻烦的需求。比如七彩黑、根据手机壳改变app的颜色等等,你怎么看?虽然一般情况下并没有那么难,但是有些需求在刚拿到的时候还是会很吃力。表之间的数据传递曾经遇到过这样一个需求:A表的数据需要继承B表的数据,步骤越少越好。这到底是什么意思?意思是实现类似下面的效果:这个应该是这样的,你可以直接告诉产品,对不起,实现不了。但是产品告诉我,不行不行,必须实现。别无选择,只能妥协。整理OK,我们来梳理一下思路,首先确定现有的主要开发环境:framework:reactUIlibrary:antd既然要实现上图所示的拖拽效果,那么一系列的HTML5拖拽API(Drag和Drop等)一定是主角。可以在此处探索本机API和用法。熟悉API之后,我们需要分析需求,明确三个重点:第一是拖拽动作,用拖拽API可以很好的解决;二是表与表之间的数据交互,即如何将表B中的部分数据(流水号)添加到表A中(继承信息);三是表格B中每一行的序号与表格A中的使用信息是一对多的关系,表格A中的使用信息是可以添加或替换的。弄清楚需要解决的要点后,我们就可以开始编码了。首先,我们需要创建两个表并创建假数据:importReact,{Component}from'react';从'antd'导入{Table,Row,Col,Button};导出类App扩展组件{columnsAcolumnsBconstructor(props){super(props);this.columnA=[{title:'Name',dataIndex:'name',key:'name',},{width:100,title:'Information',dataIndex:'obj',key:'obj',}]this.columnsB=[{title:'序列号',dataIndex:'num',key:'num',},{title:'information',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(<表列={this.columnsA}dataSource={this.state.dataSourceA}/><表列={this.columnsB}dataSource={this.state.dataSourceB}/>

)}}效果如下:接下来就是实现拖拽动作了,因为这里用到了antd的Table组件,自然而然的就可以想到在columns上做文章,实现这里的原生拖拽API扩展序号是需要拖拽的元素,继承信息是需要接收的元素。为了让拖拽更加明显,我们这里也加一点样式:this.columnA=[{title:'name',dataIndex:'name',key:'name',},{width:100,title:'继续信息',dataIndex:'obj',key:'obj',render:(value,row,index)=>{return{e.preventDefault();this.drop(e)}}onDragOver={this.allowDrop}>{value}
}}]this.columnsB=[{title:'序列号',dataIndex:'num',key:'num',render:(value,row,index)=>{return{this.drag(e)}}>{value}
}},{title:'Information',dataIndex:'info',key:'info',}]drag=(e)=>{console.log(e)};drop=(e)=>{console.log(e);};allowDrop=(e)=>{e.preventDefault();};效果如下:拖拽动作可用,但是两张表的数据没有变化,所以接下来我们需要处理数据,想要传递数据,可以使用拖拽API:dataTransfer.setData()方法设置拖拽数据的数据类型和值;dataTransfer.getData()方法获取拖拽数据,该方法将返回任何在setData()方法中设置为相同类型的数据.//columnsA{width:100,title:'沿用信息',dataIndex:'obj',key:'obj',render:(value,row,index)=>{return{e.防止默认();this.drop(e)}}onDragOver={this.allowDrop}>{value}
}}//columnsB{title:'序号',dataIndex:'num',key:'num',render:(value,row,index)=>{return{this.drag(e,value)}}>{value}}},drag=(e,value)=>{console.log(e)e.dataTransfer.setData('value',value)};drop=(e,key)=>{letvalue=e.dataTransfer.getData('value')console.log("获取数据:",value);};可以看到我们已经能够把拖拽的数据取出来了最后,我们需要处理A表的数据,首先遍历dataSourceA,如果其中元素的key和接收数据的元素的key相等,则给这个元素的obj字段赋值://columnsA{width:100,title:'ContinueInformation',dataIndex:'obj',key:'obj',render:(value,row,index)=>{return{e.preventDefault();这。drop(e,row.key)}}onDragOver={this.allowDrop}>{value}}}drop=(e,key)=>{letvalue=e.dataTransfer.getData('value')console.log("获取数据:",value);让数据=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...最后很多情况遇到的问题好像有点麻烦,不过分析一下细心,然后正确拆解问题总能找到更好的解决办法。如果文章中有什么不足或者更好的建议,欢迎提出来一起讨论~