首页 技术 正文
技术 2022年11月18日
0 收藏 759 点赞 4,929 浏览 2549 个字

一、问题描述

问题是这样的,后台传了xArr = [x1, x2,…,xn]和yArr = [y1, y2, ..yn]两个数组,前端要渲染出表格并且可以填写每个单元格的值,然后按照一定数据结构保存并传给后台,并且再次获取这个数据结构和数组xArr、yArr可以自己渲染出这个表?实现新增和修改的功能。大致界面效果如下图所示:

动态渲染可编辑单元格的Table

y1, y2,…,yn作为列名,x1,x2, …, xn作为第一列数据,此业务模型是一种常见的表格,只不过要求行列都不固定,由后台数据提供并且动态生成。还要能够实现修改功能。本质上是一个动态渲染可编辑Table的问题。难点在于动态构建表格并且实现数据展示和保存。

二、解决思路

(1)数据转换成表格后,处理起来就简单了,如果以常见的Table组件为例,只需要构建columns和dataSource两个数组数据即可渲染出表格;

(2)渲染出表格后,表格每一个余下的单元格都要可输入,可以考虑单元格利用render渲染出Input组件,通过Input的操作onChange或onBlur去改变数据并存储。

(3)数组是引用类型,可以利用引用类型只要没有深拷贝或改变指针指向内存地址就不变的原理,方便记录操作后的数据。

三、解决方法(以React结合ant design UI的Table组件为例):

(1)动态构建columns(表格列数据)和dataSource(表格数据源)渲染出表格。(Table可参考 https://ant.design/components/table-cn/#header)

 const xArr = ['x1', 'x2', 'x3', 'x4'];
const dataSource = xArr.map((v, i) => ({
key: String(i),//此处自定义表格每一行的唯一key,如果没有设置唯一标志会报错
y0: v,//第一列数据即显示X1-Xn的那一列
})); const yArr = ['y1', 'y2', 'y3', 'y4', 'Y5'];
const columns = [{
title: ' ',
dataIndex: 'y0',//第一列y0为列的dataIndex,用于显示x1-xn
}, ...yArr.map(item => ({//其他列通过yArr循环得到,并用...解构直接合并为columns
title: item,
dataIndex: item,
}))];

这样就得到形如dataSource = [{ key: ‘0’, y0:’x1′}, { key: ‘0’, y0:’x1′},…];  columns = [{ title: ”, dataIndex: ‘y0’},{ title: ‘y1’, dataIndex: ‘y1’},…];的表格数据,将此数据源传入表格组件Table,即可渲染出表格如下:

<Table columns={columns} dataSource={dataSource} />

动态渲染可编辑单元格的Table

(2)表格添加Input并且根据onChange/onBlur事件动态记录dataSource的变化。

 const columns = [{
title: ' ',
dataIndex: 'y0',
}, ...yArr.map(item => ({
title: item,
dataIndex: item,
render: (text, record) => (
<Input defaultValue={record[item]} onChange={(e) => { record[item] = e.target.value; }} />
),
}))];

渲染效果如下:

动态渲染可编辑单元格的Table

四、完整代码

/**
* @author xiao-pengyou
* @create date 2019-03-27
* @desc 动态可编辑表格
* */import React, { PureComponent } from 'react';
import { Table, Input } from 'antd';export default class Demo extends PureComponent {
state = { dataSource: [] }; componentDidMount() {
const xArr = ['x1', 'x2', 'x3', 'x4'];
const dataSource = xArr.map((v, i) => ({key: String(i),y0: v}));
this.setState({ dataSource });//dataSource不能在render里面构建,在render里面构建每次重新渲染的时候dataSource会被重新构建,指针指向变化导致先前的修改不能被跟踪
} render() {
const yArr = ['y1', 'y2', 'y3', 'y4', 'y5'];
const that = this;//定义中间量that=this确保columns内部onChange事件作用域为当前组件,方便调用forceUpdate()强制渲染表格
const columns = [{
title: ' ',
dataIndex: 'y0',
}, ...yArr.map(item => ({
title: item,
dataIndex: item,
render: (text, record) => (
<Input value={record[item]} onChange={(e) => { record[item] = e.target.value; that.forceUpdate(); }} />
),
}))];//最终的dataSource就是我们想要的数据结构,修改时直接把这个dataSource传给构建的表格就可以渲染
return <Table columns={columns} dataSource={this.state.dataSource} bordered pagination={false} />;//bordered设置边框,pagination=false取消分页功能,可以不用在意此参数
}
}

  最终效果(控制台输出为提交给后台的dataSource数组):

动态渲染可编辑单元格的Table

以上就是一个动态列的可编辑表格的React实现方式。如有问题欢迎留言批评指正,谢谢!

本文为原创博客,非法抄袭或复制将追究法律责任,转载请注明出处:https://www.cnblogs.com/xiao-pengyou/

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,030
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,520
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,368
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,148
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,781
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,859