Ant Design穿梭框:Transfer组件数据交互实现

Ant Design穿梭框:Transfer组件数据交互实现

【免费下载链接】ant-design An enterprise-class UI design language and React UI library 【免费下载链接】ant-design 项目地址: https://gitcode.com/gh_mirrors/antde/ant-design

组件概述

Ant Design的Transfer(穿梭框)组件是一个双栏穿梭选择框,用于在两个列表之间移动数据项。它主要应用于以下场景:

  • 需要在多个可选项中进行多选时
  • 比起Select和TreeSelect,需要展示更多信息时

该组件位于项目的components/transfer/目录下,核心实现文件为components/transfer/index.tsx

基本用法

Transfer组件最基础的用法是展示两个列表,通过方向按钮在列表间移动选项。基本实现代码如下:

import { Transfer } from 'antd';

const App = () => {
  const [targetKeys, setTargetKeys] = useState([]);
  const [selectedKeys, setSelectedKeys] = useState([]);
  const dataSource = [...Array(20)].map((_, i) => ({
    key: i.toString(),
    title: `选项 ${i + 1}`,
    description: `选项 ${i + 1} 的描述信息`,
  }));

  return (
    <Transfer
      dataSource={dataSource}
      targetKeys={targetKeys}
      selectedKeys={selectedKeys}
      onChange={setTargetKeys}
      onSelectChange={setSelectedKeys}
      render={(item) => `${item.title}-${item.description}`}
    />
  );
};

这个基础示例展示了Transfer组件的核心功能:

  • 左侧列表显示可用选项
  • 右侧列表显示已选选项
  • 可通过中间的方向按钮移动选项

核心API参数

Transfer组件提供了丰富的API来自定义其行为,主要参数包括:

参数说明类型默认值
dataSource数据源,渲染到左边一栏中RecordType[][]
targetKeys显示在右侧框数据的key集合TransferKey[][]
selectedKeys设置哪些项应该被选中TransferKey[][]
render每行数据渲染函数(record) => ReactNode-
onChange选项在两栏之间转移时的回调(targetKeys, direction, moveKeys) => void-
onSelectChange选中项发生改变时的回调(sourceSelectedKeys, targetSelectedKeys) => void-

完整的API文档可参考components/transfer/index.zh-CN.md

数据交互核心实现

数据处理流程

Transfer组件的数据处理核心逻辑位于components/transfer/hooks/useData.ts文件中。该hooks负责:

  1. 处理数据源,为每个项添加唯一key
  2. 根据targetKeys分离左右列表数据
  3. 提供过滤和排序功能

核心代码逻辑如下:

// 简化版数据处理逻辑
const useData = (dataSource, rowKey, targetKeys) => {
  // 处理数据源,确保每个项都有key
  const mergedDataSource = (dataSource || []).map((record) => {
    const key = rowKey ? rowKey(record) : record.key;
    return { ...record, key };
  });
  
  // 分离左右列表数据
  const leftDataSource = mergedDataSource.filter(
    (item) => !targetKeys.includes(item.key)
  );
  const rightDataSource = mergedDataSource.filter(
    (item) => targetKeys.includes(item.key)
  );
  
  return [mergedDataSource, leftDataSource, rightDataSource];
};

选择状态管理

选择状态管理由components/transfer/hooks/useSelection.ts实现,负责维护选中项的状态:

// 简化版选择状态管理
const useSelection = (leftDataSource, rightDataSource, selectedKeys) => {
  const [sourceSelectedKeys, setSourceSelectedKeys] = useState([]);
  const [targetSelectedKeys, setTargetSelectedKeys] = useState([]);
  
  // 处理选中项变化逻辑
  // ...
  
  return [
    sourceSelectedKeys,
    targetSelectedKeys,
    setSourceSelectedKeys,
    setTargetSelectedKeys
  ];
};

移动选项实现

移动选项的核心逻辑在Transfer组件的moveTo方法中实现:

const moveTo = (direction) => {
  // 确定要移动的键
  const moveKeys = direction === 'right' ? sourceSelectedKeys : targetSelectedKeys;
  
  // 过滤禁用选项
  const dataSourceDisabledKeysMap = groupDisabledKeysMap(mergedDataSource);
  const newMoveKeys = moveKeys.filter((key) => !dataSourceDisabledKeysMap.has(key));
  
  // 更新目标键集合
  const newTargetKeys = direction === 'right'
    ? newMoveKeys.concat(targetKeys)
    : targetKeys.filter((targetKey) => !newMoveKeys.includes(targetKey));
  
  // 清空选中状态
  const oppositeDirection = direction === 'right' ? 'left' : 'right';
  setStateKeys(oppositeDirection, []);
  
  // 触发回调
  onChange(newTargetKeys, direction, newMoveKeys);
};

高级功能

带搜索功能

Transfer组件支持搜索过滤功能,只需设置showSearch为true:

<Transfer
  dataSource={dataSource}
  targetKeys={targetKeys}
  showSearch
  filterOption={(inputValue, item) =>
    item.title.toLowerCase().includes(inputValue.toLowerCase())
  }
/>

搜索功能的实现位于components/transfer/search.tsx文件中。

自定义渲染

Transfer组件支持高度自定义的渲染方式,包括自定义列表内容、标题和底部内容:

<Transfer
  dataSource={dataSource}
  targetKeys={targetKeys}
  render={(item) => (
    <div>
      <div>{item.title}</div>
      <div style={{ fontSize: 12, color: '#666' }}>{item.description}</div>
    </div>
  )}
  footer={(props) => (
    <div>
      <Button size="small" onClick={props.clear} disabled={props.disabled}>
        清空
      </Button>
    </div>
  )}
/>

表格穿梭框

Transfer组件支持与Table组件结合使用,实现更复杂的数据展示和选择功能:

<Transfer
  dataSource={dataSource}
  targetKeys={targetKeys}
  rowKey="key"
>
  {({ direction, filteredItems, onItemSelect, selectedKeys }) => (
    <Table
      dataSource={filteredItems}
      rowKey="key"
      pagination={false}
      rowSelection={{
        type: 'checkbox',
        selectedRowKeys: selectedKeys,
        onChange: (keys) => onItemSelect(keys, true),
      }}
    >
      <Table.Column title="姓名" dataIndex="name" key="name" />
      <Table.Column title="年龄" dataIndex="age" key="age" />
    </Table>
  )}
</Transfer>

这个高级示例的完整实现可参考components/transfer/demo/table-transfer.tsx

常见问题与注意事项

数据唯一性

按照React的规范,所有的组件数组必须绑定key。在Transfer中,dataSource里的数据值需要指定key值。如果数据没有这个属性,务必使用rowKey来指定数据列的主键:

// 当数据主键是uid时
<Transfer rowKey={(record) => record.uid} />

异步数据加载

处理异步数据加载时,可以通过控制dataSource来实现:

const [dataSource, setDataSource] = useState([]);
const [loading, setLoading] = useState(false);

useEffect(() => {
  setLoading(true);
  fetchData().then(data => {
    setDataSource(data);
    setLoading(false);
  });
}, []);

return (
  <Transfer
    dataSource={dataSource}
    loading={loading}
    // 其他属性
  />
);

性能优化

当处理大量数据时,建议使用分页功能来优化性能:

<Transfer
  dataSource={dataSource}
  pagination={{ pageSize: 10 }}
/>

总结

Ant Design的Transfer组件提供了强大而灵活的数据穿梭功能,通过本文的介绍,我们了解了:

  1. Transfer组件的基本用法和核心API
  2. 数据交互的核心实现原理
  3. 高级功能如自定义渲染和表格集成
  4. 常见问题和性能优化建议

更多详细的使用示例可以参考components/transfer/demo/目录下的文件,包括基本用法、搜索功能、高级自定义等多种场景的实现。

【免费下载链接】ant-design An enterprise-class UI design language and React UI library 【免费下载链接】ant-design 项目地址: https://gitcode.com/gh_mirrors/antde/ant-design

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值