Skip to content

AntdTable表格

Antd Table无法选择&多选问题,根据antd table 可选择案例,发现点击任意元素都会变成全选,或者取消全选,无法单个选择

原因dataSource 里面没有key属性,需要给Table 添加 rowKey="id"

Ant table表格选中后点击下一页上一页选中的内容丢失

只需要在 Table 标签的 rowSelection 属性对象内输入

preserveSelectedRowKeys: true , 即可

text
let rowSelection = { preserveSelectedRowKeys: true, };
<Table  rowSelection={rowSelection}  />

antd中如何实现分页勾选记住之前的选项

https://blog.csdn.net/baidu_41601048/article/details/124216473?spm=1001.2014.3001.5502

js
const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 表格数据

const rowSelection = {
	selectedRowKeys,
	onSelect: (record, selected, selectedRow) => {
		console.log('record:', record);
		let keys = [...selectedRowKeys];
		if (selected) {
			keys = [...selectedRowKeys, record.id];
		} else {
			keys = selectedRowKeys.filter((item) => item !== record.id);
		}
		setSelectedRowKeys(keys);
	},
	onSelectAll: (selected, selectedRows, changeRows) => {
		if (selected) {
			const addCheckedKeys = changeRows.map((item) => {
				return item.id;
			});
			setSelectedRowKeys([...selectedRowKeys, ...addCheckedKeys]);
		} else {
			const subCheckedKeys = selectedRowKeys.filter((id) => {
				return !changeRows.some((item) => {
					return item.id === id;
				});
			});
			setSelectedRowKeys(subCheckedKeys);
		}
	}
};

我们需要给表格每行加上这个rowkey,让它和我们数据里的某个字段绑定起来。 rowKey={record => record.id} 这里我们通过id,因为selectedRowKeys我们记录的也是id。

所以我们把table改造如下:

text
 <Table    
   rowKey={record => record.id}
   hideSelectAll={true}
   rowSelection={rowSelection}
   columns={columns}
   dataSource={tableList}
   pagination={paginationProps}
>
</Table>

在应用table中最好还是要设置唯一的rowKey才能更好的优化性能,并且一定不要把rowKey设置成索引值,以防出现不必要的bug。

在Ant Design的Table组件中实现分页全选功能,通常涉及两个关键点:一个是实现表格行的多选,另一个是在分页之间同步选中状态。 selectedRowKeys 是一个状态变量,用于保存当前选中的行键(key),onSelectAll 函数会在点击全选按钮时触发,用来更新所有当前页的行是否被选中。 由于表格默认只处理当前页的选中状态,要在翻页时保留选中状态,你需要在服务器端或客户端全局维护选中行的键值集合。当数据分页加载时,需判断每一项数据是否在选中集合内,并相应设置其初始选中状态。

对于跨页全选,你可能需要自定义全选功能,例如在顶部增加一个全选/全不选的Checkbox,然后在它的onChange事件中处理所有页的数据。 但是,原生Ant Design的Table组件并不支持直接跨页全选,你需要自己扩展这个功能,遍历所有数据并更新selectedRowKeys。

建议: 前面几页选几个数据 到后面全选再取消 selectAll的rows会因为reserve-selection有数据 全选取消只针对当前页

select:行内多选框状态变化时触发的事件,有两个参数selection(勾选的行数组),row(发生变化行的数据)。 select-all:全选多选框变化时触发的事件,也就是表头的多选框,该事件只有一个参数selection。 声明一个空数组multipleSelection,并且绑定上面两个事件。 当勾选单个数据时,触发select,我们通过selection中是否包含row判断当前行是选中还是取消,如果选中就用unshift添加到数组中, 如果是取消就将该行从数组用splice方法删除,splice需要知道下标位置,这里我们用findIndex方法获取下标

全选多选框有三种状态,全选,半选,取消,重点考虑半选状态,半选也就是说有某些行已经选过了,此时再全选就有两种思路: 将数据全部添加到数组然后去重。 获取未被单独勾选的添加到数组。 刚好最近学习lodash源码库,这里我们借助lodash库用第二种方式实现,里面有一个lodash.differenceBy方法,可以让我们获取到未被勾选的单独数据,并且该方法也能兼容全选。 最后取消,我们就用filter过滤掉当前list的数据。

在控制表单的选项时使用slectionRows作为选中的数据时,使用pagination翻页时,选择下页的数据会覆盖前面选择的数据,使用slectionRowKeys时就不会有这个问题

antd表格如何实现全选,如何在表格以外去控制表格全选?

今天碰到这样一个需求:在表格之外通过一个按钮去控制表格的全选。 由于对antd组件库不熟悉,导致走了很多弯路:

antd里如何实现基本的全选的?

官方的demo文档里给了一个简单的demo 没错,就是这个rowSelection,因为添加了这个属性,所以table头部的复选框能实现选中全部勾选,取消勾选,全部不选中。 经过进一步的摸索,发现api里还有这么一句话: selectedRowKeys 指定选中项的 key 数组,需要和 onChange 进行配合

经过尝试发现。它就是解决这个问题的关键。table全选的状态,完全依靠这个数组。 这个数组是当前数据的key 的集合,如果勾选了两条数据,那么这个selectedRowKeys的值就是这两条数据的key 的集合。 如果勾选了表格所有的行,那么这个selectedRowKeys就说整个data的key的集合。 接下来我们大胆的尝试,给表格外面checkbox的checked绑定一个值,true表示全选(勾选)。 此时我们把data的key全部取出来赋值给selectedRowKeys,就能达到目的,

jsx
 const columns = [
	{
		title: 'Name',
		dataIndex: 'name',

	},
	{
		title: 'Age',
		dataIndex: 'age',
	},
	{
		title: 'Address',
		dataIndex: 'address',
	},
];

const data = [];
for (let i = 0; i < 10; i++) {
	data.push({
		key: i,
		name: `天然气安装 ${i}`,
		code: `00000-${i}`,
		unit: `米`,
		price: 2349.00,
		fuliao: 2,
		status: `${i}`,
		mark: "xxxxxxxxxxx",
		operate: null
	});
}

function TypeProdPage() {

	const router = useHistory()
	const [isCheckedAll, setCheckAll] = useState(false)
	const [selectedRowKeys, setSelectedRowKeys] = useState([])
	const [isCheckeAll, setIsCheckeAll] = useState(false)

	const onSelect = () => {

	}
	const onCheck = () => {

	}
	const selectAll = (e) => {
		if (e.target.checked) {
			let keys = [];
			data.forEach(i => keys.push(i.key))
			setSelectedRowKeys(keys) //这里是关键
		} else {
			setSelectedRowKeys([])
		}
		setIsCheckeAll(e.target.checked)
	}
	const rowSelection = {
		onChange: (selectedRowKeys, selectedRows) => {
			if (selectedRowKeys.length === data.length) {
				setSelectedRowKeys(selectedRowKeys)
				setIsCheckeAll(true)  //同步更改表格外面checkbox的状态
			} else {
				setSelectedRowKeys(selectedRowKeys)
				setIsCheckeAll(false)  //同步更改表格外面checkbox的状态
			}
		},
		selectedRowKeys,
		getCheckboxProps: (record) => ({
			disabled: record.name === 'Disabled User',
			name: record.name,
		}),
	};
	const renderTitle = (data) => {
		console.log("data:", data)
		return <div className="tree-item">
			<div className="tree-txt">{data.title}</div>
			<div className="tree-oper-btn">a</div>
		</div>
	}


	return (
		<div className="type-prod-page">
			<Tabs defaultActiveKey="1" size="large">
				{
					combo.map(item =>
						(<TabPane tab={item.name} key={item.id}>
								<div className="tab-container">
									<div className="tree-menu">
										<Tree
											defaultExpandParent
											onSelect={onSelect}
											treeData={treeData}
											titleRender={
												renderTitle
											}
										/>
									</div>
									<div className="content">
										<Table
											title={(data) =>
												<div className="table-title">
													<Row>
														<Col span={12}>
															<Checkbox onChange={(e) => selectAll(e)} checked={isCheckeAll}>全选</Checkbox>
															已选<span>2</span>个对象,共1200个对象
														</Col>
														<Col span={12}>
															<Space>
																<Button type="primary">添加定额</Button>
																<Button type="primary">编辑</Button>
																<Button type="primary">移除</Button>
															</Space>
														</Col>
													</Row>
												</div>
											}
											hideSelectAll={true}
											rowSelection={rowSelection}
											columns={columns}
											dataSource={data}
										>
										</Table>
									</div>
								</div>
							</TabPane>
						)
					)
				}
			</Tabs>
		</div>
	)

表头 scroll 固定列

(1)对于列数很多的数据,可以固定前后的列,横向滚动查看其它数据,需要和 scroll.x 配合使用。若列头与内容不对齐或出现列重复,请指定固定列的宽度 width。如果指定 width 不生效,请尝试建议留一列不设宽度以适应弹性布局,或者检查是否有超长连续字段破坏布局。

(2)建议指定 scroll.x 为大于表格宽度的固定值或百分比。注意,且非固定列宽度之和不要超过 scroll.x。

处理antd table其中某一项的值如果超出,使用....显示:

text
{
	title: 'config_content',
		key: 'Content',
		onCell: () => {
		return
		{
			style: {
				maxWidth: 600,
					overflow: 'hidden',
					whiteSpace: 'nowrap',
					textOverflow: 'ellipsis',
					cursor: 'pointer'
			}
		}
	},

提示

在Table中,其中某一列的内容太长时,可以使用 ellipsis:{showTitle:true},超过宽度将自动省略,暂不支持和排序筛选一起使用。 设置为 true 或 { showTitle?: boolean } 时,表格布局将变成 tableLayout="fixed"布局,但是会和部分样式冲突,造成样式错位情况。

可以在渲染时,对内容进行处理。

overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis', width: '120px

react中如何实现类似vue中的slot功能?

https://blog.csdn.net/baidu_41601048/article/details/123133443?spm=1001.2014.3001.5502

实现 Ant Table 可伸缩列(列宽度可拖拽)

还需要引入"react-resizable/css/styles.css" https://juejin.cn/post/7182423243553734717?searchId=20240424224719110BB47F5CE46FC68325

列数多了确实会造成卡顿,因为拖动过程让表格不断重新渲染。 可以使用另一种技术方案: 拖动时只改变光标,等拖动结束时,再更新表格列宽,从而只渲染一次表格。当然,拖动时没有实时更新页面,体验会差些。

可以试试对拖动的回调函数 onResize ,使用函数节流,减少渲染页面的次数

Contributors

作者:Long Mo
字数统计:2.2k 字
阅读时长:7 分钟
Long Mo
文章作者:Long Mo
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Longmo Docs