逐行解析Antd Design可编辑单元格
作者:互联网
解析Antd Design可编辑单元格
背景:
在项目中肯定不免需要类似这样的表格,在单元格里面进行编辑。类似这样:
逻辑:
这是一个可编辑表格,那么就需要确定的是每次点击编辑定位到需要被编辑的那一行。就比如说我点击了第一行,那么就只能是第一行可以被编辑,其余几行都处于禁用状态。
关键代码:
我用的是antd design组件库,详情可以去官网:https://ant.design/components/table-cn/#components-table-demo-edit-cell
columns是表格列的配置。有些关键参数我在这边做些说明:
align | 设置列的对齐方式 |
---|---|
dataIndex | 列数据在数据项中对应的路径,支持通过数组查询嵌套路径 |
editable | 是否可编辑 |
render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并 |
title | 列头显示文字(函数用法 3.10.0 后支持) |
width | 列宽度 |
editingKey
就相当于是一个标识,当editingKey
为''
时,就无法编辑,当其有值时就可以编辑。
isEditing
函数就是把需要编辑的那一行值的key
赋``editingKey值并且返回。在
columns`中就根据这个返回的值来判断是否需要编辑。
const [editingKey, setEditingKey] = useState('');
const isEditing =(record) => {
return record.key === editingKey
};
const columns = [
{
title: '操作',
dataIndex: 'operation',
align: 'center',
width: '140px',
render: (_, record) => {
const editable = isEditing(record);
return editable ? (
<span>
<a
style={{marginRight: 8}}
onClick={() => {
save(record.key)
}}
>
保存
</a>
<a
style={{marginRight: 8}}
onClick={() => {
cancel();
}}
>
取消
</a>
</span>
)
: (
<a
disabled = {editingKey !== ''}
onClick = {() => {
edit(record)
}}
>编辑</a>
)
}
},
{
title: '供应商名称',
dataIndex: 'accountName',
width: '150px',
editable: true,
},
{
title: '供应商代码',
dataIndex: 'supplierCode',
width: '150px',
editable: true,
},
{
title: '开户行',
dataIndex: 'bankName',
width: '250px',
editable: true,
},
{
title: '账号',
dataIndex: 'accountNumber',
width: '250px',
editable: true,
},
];
点击编辑时触发该函数,把单元格里面的数据赋值到编辑框里面。说的直白一点就是当点击编辑框的时候,会出现新的输入组件,但是这个Input
组件没有值,如果我们只是修改某个字的话又要重新输入一遍,所以需要把原来单元格的值赋值给输入框。
//编辑
const edit =(record) => {
form.setFieldsValue({
...record
});
setEditingKey(record.key)
};
取消的思想就是把editingKey
赋值为''
,随后recoed.key
值也为''
,就取消了编辑状态了。
//取消
const cancel =() => {
setEditingKey('');
};
我在这边把编辑的组件单独封装了起来,因为可能不止一个页面需要调用该组件。
先引入该组件,具体的路径因人而异。
import EditableTable from './editableTable';
具体使用如上图所示,源码如下:
有几个属性有必要说明一下,columns
就是上文定义的表格列,scroll
定义的是表格滚动区域的宽和高,data
就是表格里面的数据了,这是从后端拿到的,settableselectedvalue
是表格多选时选中的数据,loading
是显示页面是否加载中的一个小动画。
<Form form={form} >
<EditableTable
columns={columns}
scroll={{ x: 500, y: 500 }}
style={{ width: '90%' }}
data={data}
isEditing={isEditing}
setSelectedData={settableselectedvalue}
loading={props.loading}
/>
</Form>
现在来看被封装的EditableTable
里面的代码:相关的注释已经写在了代码块里
import React, { useState } from 'react';
import { Table, Input, InputNumber, Select, Form } from 'antd';
// 这里是编辑
function EditableTable(props) {
const { Option } = Select;
const { TextArea } = Input;
const EditableCell = ({
editing,
dataIndex,
title,
inputType,
record,
index,
requiring,
selectOptions,
children,
...restProps
}) => {
return (
// <td> 是table data cell 是用于定义表格中的单元格,必须嵌套在<tr>标签中
<td {...restProps}>
{/* 编辑栏中先是判断是否编辑,如果editing等于某个值,即为真,如果为真,就执行<Form.Item>里面的内容。如果为假,就执行children,继承子节点上的内容
在Form里面又有一个是selectOptions的三目运算法, */}
{editing ? (
<Form.Item
name={dataIndex}
style={{
margin: 0,
}}
rules={[
{
required: requiring,
message: `请输入 ${title}!`,
},
]}
>
{selectOptions ? selectOptions : <TextArea />}
</Form.Item>
) : (
children
)}
</td>
);
};
// 合并col
// 把传进来的columns依次遍历,如果columns里面的editable不为true,就原封不动的返回
const mergedColumns = props.columns.map(col => {
if (!col.editable) {
return col;
}
return {
// 把不需要编辑的那一行依次浅拷贝
...col,
// 重新设置单元格的属性
onCell: record => ({
record,
inputType: 'text',
dataIndex: col.dataIndex,
title: col.title,
requiring: col?.required == false ? false : true,
selectOptions: col?.selectOptions ? col.selectOptions : null,
editing: props.isEditing(record),
}),
};
});
return (
<Table
// components覆盖默认的 table 元素
components={{
body: {
cell: EditableCell,
},
}}
bordered
loading={props.loading}
// dataSource就是需要被展示的值,props是父元素传进来的值,包含了所有引用该组件时传进来的所有值,我们需要展示的值data数据也在其中
dataSource={props.data}
scroll={props.scroll}
columns={mergedColumns}
// 分页
pagination={{
showTotal: (total, range) => `本页${range[1] - range[0] + 1}条,共 ${props.data.length} 条`,
onChange: props.cancel,
defaultPageSize: '50',
}}
style={props.style}
size="middle"
scroll={{ x: '75%', y: 500 }}
// 多选操作
rowSelection={{
onChange: (selectedRowKeys, selectedRows) => {
props.setSelectedData(selectedRows);
},
}}
/>
);
}
export default EditableTable;
标签:const,record,单元格,编辑,Design,props,title,col,逐行 来源: https://blog.csdn.net/qq_40830369/article/details/121954441