ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Ant Design Transfer 穿梭框组件完全指南:受控数据流、搜索过滤与自定义渲染

Ant Design Transfer 穿梭框组件完全指南:受控数据流、搜索过滤与自定义渲染 Ant Design Transfer 穿梭框组件完全指南受控数据流、搜索过滤与自定义渲染【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design穿梭框Transfer是 Ant Design 数据录入组件中用于双栏多选的交互控件通过左右两栏之间的方向按钮完成元素的批量移动选择。本文围绕 components/transfer/index.zh-CN.md 的官方文档展开结合仓库内组件源码与官方 Demo系统讲解其受控数据模型source / target、完整 API 参数、搜索过滤、单向模式、分页、Render Props 自定义列表以及异步数据加载等实战方案帮助你快速掌握从基础用法到源码级原理的完整链路。何时使用穿梭框穿梭框本质上是一个多选控件在以下场景中优于其他选择类组件需要在多个可选项中进行多选时当可选项包含较多辅助信息如描述、状态、图标等而 Select 与 TreeSelect 空间有限、无法充分展示时穿梭框以更大的空间换取信息量的展示。穿梭框用直观的方式在两栏中移动元素完成选择行为选择一个或以上的选项后点击对应的方向键即可把选中的选项移动到另一栏。其中左边一栏为source源右边一栏为target目标API 的设计也直接反映了这两个概念如dataSource、targetKeys。注意Transfer 是完全受控组件不支持非受控模式。targetKeys必须由你通过onChange回传更新组件自身不会维护目标栏数据的状态。这一点与 Select 等组件的非受控用法有本质区别。快速上手基本用法以下代码摘自仓库官方示例 components/transfer/demo/basic.tsx展示了受控用法的完整闭环——targetKeys从 state 中来onChange再把新值写回 stateimport React, { useState } from react; import { Transfer } from antd; import type { TransferProps } from antd; interface RecordType { key: string; title: string; description: string; } const mockData Array.from({ length: 20 }).mapRecordType((_, i) ({ key: i.toString(), title: content${i 1}, description: description of content${i 1}, })); // 初始时key 大于 10 的数据已处于右侧目标栏 const initialTargetKeys mockData .filter((item) Number(item.key) 10) .map((item) item.key); const App: React.FC () { const [targetKeys, setTargetKeys] useStateTransferProps[targetKeys](initialTargetKeys); const [selectedKeys, setSelectedKeys] useStateTransferProps[targetKeys]([]); const onChange: TransferProps[onChange] (nextTargetKeys, direction, moveKeys) { console.log(targetKeys:, nextTargetKeys); console.log(direction:, direction); console.log(moveKeys:, moveKeys); setTargetKeys(nextTargetKeys); }; const onSelectChange: TransferProps[onSelectChange] ( sourceSelectedKeys, targetSelectedKeys, ) { console.log(sourceSelectedKeys:, sourceSelectedKeys); console.log(targetSelectedKeys:, targetSelectedKeys); setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]); }; const onScroll: TransferProps[onScroll] (direction, e) { console.log(direction:, direction); console.log(target:, e.target); }; return ( Transfer dataSource{mockData} titles{[Source, Target]} targetKeys{targetKeys} selectedKeys{selectedKeys} onChange{onChange} onSelectChange{onSelectChange} onScroll{onScroll} render{(item) item.title} / ); }; export default App;Transfer API 详解通用属性如className、style、prefixCls等参考 通用属性文档。下表完整覆盖 Transfer 的专有参数默认值与类型均以当前仓库文档为准参数说明类型默认值版本dataSource数据源其中的数据会被渲染到左边一栏中targetKeys中指定的除外RecordType extends TransferItem TransferItem[][]disabled是否禁用booleanfalseselectionsIcon自定义下拉菜单图标React.ReactNode5.8.0filterOption根据搜索内容进行筛选接收inputValue、option、direction三个参数direction自 5.9.0 支持当option符合筛选条件时应返回 true反之返回 false(inputValue, option, direction:left|right) boolean-footer底部渲染函数(props, { direction }) ReactNode-direction: 4.17.0listStyle两个穿梭框的自定义样式object | ({direction:left|right}) object-locale各种语言{ itemUnit: string; itemsUnit: string; searchPlaceholder: string; notFoundContent: ReactNode | ReactNode[]; }中文环境为{ itemUnit: 项, itemsUnit: 项, searchPlaceholder: 请输入搜索内容 }oneWay展示为单向样式booleanfalse4.3.0operations操作文案集合顺序从上至下string[][, ]operationStyle操作栏的自定义样式CSSProperties-pagination使用分页样式自定义渲染列表Render Props下无效boolean | { pageSize: number, simple: boolean, showSizeChanger?: boolean, showLessItems?: boolean }false4.3.0render每行数据渲染函数入参为dataSource中的项返回 ReactElement或返回一个普通对象其中label字段为 ReactElement用于展示value字段为 title用于标题与搜索匹配(record) ReactNode-selectAllLabels自定义顶部多选框标题的集合按左右两栏顺序(ReactNode | (info: { selectedCount: number, totalCount: number }) ReactNode)[]-selectedKeys设置哪些项应该被选中受控选中态string[] | number[][]showSearch是否显示搜索框booleanfalseshowSelectAll是否展示全选勾选框booleantruestatus设置校验状态error | warning-4.19.0targetKeys显示在右侧框数据的 key 集合受控string[] | number[][]titles标题集合顺序从左至右ReactNode[]-onChange选项在两栏之间转移时的回调函数(targetKeys, direction, moveKeys): void-onScroll选项列表滚动时的回调函数(direction, event): void-onSearch搜索框内容改变时的回调函数(direction:left|right, value: string): void-onSelectChange选中项发生改变时的回调函数(sourceSelectedKeys, targetSelectedKeys): void-说明表内dataSource数据类型链接指向 components/transfer/index.tsx 中的TransferItem定义其约定字段为key、title、description、disabled并支持[name: string]: any扩展任意自定义字段。源码视角受控数据流如何运转从 components/transfer/index.tsx 的源码结构可以推断组件的内部数据流水线数据拆分useDataHook 依据rowKey为每条记录补充key并按targetKeys将dataSource拆分为leftDataSource与rightDataSourcecomponents/transfer/hooks/useData.ts。右侧数据严格按targetKeys的顺序排列左侧数据保持dataSource原顺序。选中态拆分useSelectionHook 将外部传入的selectedKeys自动过滤为左、右两栏各自的选中集合components/transfer/hooks/useSelection.ts并监听数据变化自动剔除已失效的 key。移动逻辑moveTo方法components/transfer/index.tsx会先过滤掉被禁用项再合并/剔除targetKeys最后清空对侧选中态并触发onChange。这就是为什么点击方向键后新targetKeys必须回写 state否则视图不会变化。源码视角操作栏按钮行为中间操作栏由 components/transfer/operation.tsx 渲染右侧移到目标栏按钮的disabled取决于右侧是否有选中项rightActive即sourceSelectedKeys.length 0左侧按钮同理启用oneWay后左侧返回按钮会被整体移除。RTL 环境下箭头图标方向会自动翻转。搜索与过滤带搜索框的穿梭框showSearch开启后每栏顶部会显示搜索框默认按render返回的文本做包含匹配。要自定义匹配规则使用filterOption。示例来自官方 Demo components/transfer/demo/search.tsxconst filterOption (inputValue: string, option: RecordType) option.description.indexOf(inputValue) -1; const handleSearch: TransferProps[onSearch] (dir, value) { console.log(search:, dir, value); }; return ( Transfer dataSource{mockData} showSearch filterOption{filterOption} targetKeys{targetKeys} onChange{handleChange} onSearch{handleSearch} render{(item) item.title} / );搜索交互的底层行为位于 components/transfer/list.tsx 的matchFilter优先使用自定义filterOption(filterValue, item, direction)注意direction参数自 5.9.0 起传入未提供时退化为text.includes(filterValue)的包含匹配。搜索后列表的全选只作用于过滤后的可见项且自动跳过disabled项components/transfer/list.tsx。单向模式与高级用法单向样式oneWay自 4.3.0 起支持oneWay为true时只保留移动到右侧的按钮右侧列表可勾选并支持单项移除通过onRightItemRemove回调更新targetKeys见 components/transfer/index.tsx。适合权限分配、发布流程等只增不减的强流程场景官方 Demo 见 components/transfer/demo/oneWay.tsx。高级用法advanced官方 Demo components/transfer/demo/advanced.tsx 组合了搜索、自定义操作文案、禁用项、底部渲染footer等可作为复杂场景的起点模板。分页pagination大数据量下开启分页可避免长列表渲染卡顿支持pageSize、simple简洁分页、showSizeChanger、showLessItems。注意源码中 components/transfer/index.tsx 会给出 dev 警告pagination与自定义渲染列表children不能同时使用且分页模式下全选复选框会自动隐藏components/transfer/list.tsx。自定义状态status自 4.19.0 起支持statuserror | warning配合表单时还会自动合并Form.Item的校验状态getMergedStatus逻辑见 components/transfer/index.tsx。自定义全选文字custom-select-all-labels通过selectAllLabels数组按左、右两栏顺序传入自定义节点或函数函数接收{ selectedCount, totalCount }可实现已选 n / 共 m 项之外的个性化文案默认文案逻辑见 components/transfer/list.tsx。组件 Tokencomponent-tokenDesign Token 演示用于自定义穿梭框各部件颜色、尺寸Token 表格见下文主题变量小节。自定义渲染render 的两种返回形式render除了直接返回 ReactElement还可以返回{ label, value }对象。这一设计在 components/transfer/list.tsx 中有明确实现label作为行内容的实际展示元素value作为该行的 title鼠标悬浮提示与搜索匹配文本。官方 Demo components/transfer/demo/custom-item.tsx 演示了组合展示const renderItem (item: RecordType) { const customLabel ( span classNamecustom-item {item.title} - {item.description} /span ); return { label: customLabel, // 用于展示 value: item.title, // 用于 title 提示和搜索匹配 }; }; return ( Transfer dataSource{mockData} listStyle{{ width: 300, height: 300 }} targetKeys{targetKeys} onChange{handleChange} render{renderItem} / );listStyle既可以是普通对象也可以是接收{ direction }返回样式的函数从而为左右两栏定制不同尺寸。Render Props完全自定义列表当内置列表无法满足需求如要做成 Table、Tree、卡片等形态时Transfer 支持通过children接收一个渲染函数替代默认列表内容。函数会收到以下参数即TransferCustomListBodyProps其定义可追溯至 components/transfer/list.tsx参数说明类型版本direction渲染列表的方向left|rightdisabled是否禁用列表booleanfilteredItems过滤后的数据RecordType[]selectedKeys选中的条目string[] | number[]onItemSelect勾选条目(key: string | number, selected: boolean)onItemSelectAll勾选一组条目(keys: string[] | number[], selected: boolean)基本用法Transfer {...props}{(listProps) YourComponent {...listProps} /}/Transfer官方提供了两种典型实现可供参考表格穿梭框components/transfer/demo/table-transfer.tsx 在children中渲染 Table实现带列展示、排序的穿梭选择同时仍需在onChange中回写targetKeys保持受控。树穿梭框components/transfer/demo/tree-transfer.tsx 在children中渲染 Tree实现层级数据的穿梭选择选中逻辑依赖onItemSelect/onItemSelectAll驱动。从源码看components/transfer/index.tsx传入children后组件会设置mergedPagination !children pagination即分页在 Render Props 模式下自动失效并会触发上文提到的 dev 警告。注意key 与 rowKey遵循 React 的渲染列表规范dataSource中的每条数据必须携带唯一的key组件默认将每列数据的key属性作为唯一标识。如果你的数据没有该属性务必使用rowKey指定主键源码实现见 components/transfer/hooks/useData.tsrowKey返回的值会被写入记录的key字段// 比如你的数据主键是 uid return Transfer rowKey{(record) record.uid} /;rowKey与targetKeys/selectedKeys中使用的 key 必须保持一致否则数据无法正确分栏、选中与移动。主题变量Design TokenTransfer 支持通过 ConfigProvider 的theme.components.Transfer覆盖组件级 Design Token具体 Token 名称与默认值由站点文档中的ComponentTokenTable componentTransfer动态渲染对应实现见 components/transfer/style/index.ts可在官方组件文档页查看完整表格用于调整列表背景、标题栏颜色、操作按钮间距等视觉细节。FAQ如何支持异步数据加载穿梭框本身是同步受控组件若需要从远程服务器分页拉取数据关键在于保持页码同步在勾选时不要移除选项而是将其标记为禁用避免已加载页与后续页的 key 集合错位。官方给出的参考思路是勾选后通过dataSource中对应记录的disabled: true禁用该行同时仍保留其 key 在选中集合中从而在翻页加载新数据时维持选中状态与页码的一致性。你可以在不改变targetKeys的前提下用受控selectedKeys记录选中态并把已勾选项改为禁用实现选中但不可重复移动的效果。小结Transfer 是 Ant Design 中数据量适中、信息密度要求较高的多选场景的首选组件。其核心心智可总结为三点受控驱动targetKeys双向绑定、双栏数据模型source / target 与 API 命名一一对应、可插拔渲染render自定义行、Render Props 完全替换列表。本文覆盖了官方文档的全部 API 参数与用法并结合 components/transfer/index.tsx、components/transfer/hooks/useData.ts、components/transfer/hooks/useSelection.ts、components/transfer/list.tsx 等源码与 components/transfer/demo 系列示例为你提供了从会用到会改的完整参考路径。【免费下载链接】ant-designAn enterprise-class UI design language and React UI library项目地址: https://gitcode.com/gh_mirrors/ant/ant-design创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表