news 2026/9/20 23:16:32

Ant Design Vue Transfer 穿梭框组件完全指南:API、事件与源码级实现解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ant Design Vue Transfer 穿梭框组件完全指南:API、事件与源码级实现解析

Ant Design Vue Transfer 穿梭框组件完全指南:API、事件与源码级实现解析

【免费下载链接】ant-design-vue🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue

Transfer 穿梭框是 Ant Design Vue 中用于在双栏之间移动元素的数据录入组件,左侧一栏为source(数据源),右侧一栏为target(已选目标),API 设计也完整对应这两个概念。本文以 components/transfer/index.zh-CN.md 官方文档为核心,结合仓库内的组件源码与演示用例,系统讲解 Transfer 的全部配置项、事件回调、Render Props 自定义能力,以及底层数据流与移动逻辑的实现细节。

何时使用 Transfer

穿梭框适合以下场景:

  • 需要在多个可选项中进行多选时;
  • 相比 Select 和 TreeSelect,穿梭框占据更大的空间,可以展示可选项的更多信息(例如标题、描述等富文本内容)。

其交互方式非常直观:选择一个或以上的选项后,点击对应的方向键,即可把选中的选项移动到另一栏。dataSource中的数据默认渲染在左边一栏,targetKeys中指定的 key 除外(即已移动到右侧的数据),这一分工从组件属性设计上就清晰可见。

核心 API 全解析

Transfer 的全部属性定义位于 components/transfer/index.tsx 的transferProps()中,以下表格完整覆盖官方文档并补充了源码中的默认值与实现细节:

参数说明类型默认值版本
dataSource数据源,其中的数据将会被渲染到左边一栏中,targetKeys中指定的除外。[{key: string.isRequired, title: string.isRequired, description: string, disabled: bool}][][]
disabled是否禁用整个穿梭框booleanfalse
filterOption接收inputValueoption两个参数,当option符合筛选条件时返回true,反之返回false(inputValue, option) => boolean
footer底部自定义内容,可设置为作用域插槽slot="footer"(作用域为{ direction }
listStyle两个穿梭框的自定义样式CSSProperties{}
locale各种语言的文案配置object{ itemUnit: '项', itemsUnit: '项', notFoundContent: '列表为空', searchPlaceholder: '请输入搜索内容' }
oneWay展示为单向样式(右侧条目可直接移除)booleanfalse3.0.0
operations操作文案集合,顺序从上至下(第一项为“向右移动”按钮,第二项为“向左移动”按钮)string[]['>', '<']
operationStyle操作栏的自定义样式CSSProperties-3.0.0
pagination使用分页样式,自定义渲染列表(children 插槽)下无效boolean \| { pageSize, simple, showSizeChanger?, showLessItems? }false3.0.0
render每行数据渲染函数,入参为dataSource中的项,返回 element;或返回普通对象,其中label字段为 element、value字段为 titleFunction(record) \| slot
selectAllLabels自定义顶部多选框标题的集合VueNode \| ((info: { selectedCount, totalCount }) => VueNode)-3.0.0
selectedKeys(v-model)设置哪些项应该被选中string[][]
showSearch是否显示搜索框booleanfalse
showSelectAll是否展示全选勾选框booleantrue
status设置校验状态'error' \| 'warning'-3.3.0
targetKeys(v-model)显示在右侧框数据的 key 集合string[][]
titles标题集合,顺序从左至右string[]['', '']

关键参数源码级补充

  • pagination的默认解析逻辑:在 components/transfer/ListBody.tsx 的parsePagination中,即使只传pagination(布尔值true),内部也会合并默认配置{ pageSize: 10, simple: true, showSizeChanger: false, showLessItems: false },因此默认每页 10 条、使用简洁分页样式;传入对象时按字段覆盖。
  • rowKey的兜底机制dataSource未带key时,可用rowKey函数动态生成,源码中通过watchEffect在渲染前执行record.key = rowKey(record)(见 index.tsx)。
  • filterOption缺省行为:未提供时,list.tsx 中的matchFilter会退化为text.includes(inputValue),即对渲染后的文本做包含匹配;提供后则完全交由自定义函数决定。
  • listStyle支持函数形式:可传(style: { direction }) => CSSProperties,源码通过handleListStyle在左右两栏分别调用,实现按方向差异化布局(见 index.tsx)。

事件回调

事件名称说明回调参数版本
change选项在两栏之间转移时的回调函数(targetKeys, direction, moveKeys): void
scroll选项列表滚动时的回调函数(direction, event): void
search搜索框内容改变时的回调函数(direction: 'left' \| 'right', value: string): void-
selectChange选中项发生改变时的回调函数(sourceSelectedKeys, targetSelectedKeys): void

事件与 v-model 的联动

从 index.tsx 源码可见,targetKeysselectedKeys均通过v-model双绑(内部 emitupdate:targetKeysupdate:selectedKeys):

  • 当点击“向右”方向键时,moveTo('right')sourceSelectedKeys未禁用的条目合并进targetKeys,随后依次触发update:targetKeyschangeselectChange,并清空左侧选中态(见moveTo实现,其中通过groupDisabledKeysMap过滤掉禁用项,保证 disabled 数据不可被移动)。
  • oneWay模式下,右侧列表允许直接移除条目:onRightItemRemove会从targetKeys中过滤掉指定 key 并触发change(..., 'left', ...),此时右侧列表的头部下拉菜单显示“移除全部/移除当前页”等操作(对应 list.tsx 中showRemove分支)。
  • 搜索框内容变化时,handleFilter会 emitsearch事件,清空搜索时则 emitsearch(direction, '')

Render Props:自定义渲染列表

Transfer 支持通过children插槽接收完整的自定义列表渲染能力,官方文档给出了作用域插槽可以拿到的参数集合:

{ "direction": String, "disabled": Boolean, "filteredItems": Array, "selectedKeys": Array, "onItemSelect": Function, "onItemSelectAll": Function }

各参数说明如下:

参数说明类型版本
direction渲染列表的方向'left' \| 'right'
disabled是否禁用列表boolean
filteredItems过滤后的数据TransferItem[]
itemSelect勾选条目(key: string, selected: boolean)
itemSelectAll勾选一组条目(keys: string[], selected: boolean)
selectedKeys选中的条目string[]

官方参考示例:

<a-transfer> <template #children="{ direction, filteredItems, selectedKeys, disabled: listDisabled, onItemSelectAll, onItemSelect, }" > <your-component /> <template> </a-transfer>

从源码角度看,children插槽最终以renderList形式传入左右两个 List,并在 list.tsx 的renderListBody中渲染:只有当插槽返回了非空内容filterEmpty(bodyContent).length > 0)时才视为自定义列表,否则回退到内置的ListBody默认列表。同时,一旦使用自定义 children,pagination将自动失效(mergedPagination = !children && pagination),这正是文档中“自定义渲染列表下无效”的底层原因。

搜索与过滤的完整链路

开启show-search后,Transfer 会在每栏顶部渲染搜索框(对应 search.tsx),过滤链路如下:

  1. 用户输入触发 List 内部的handleFilter,先更新本地filterValue,再回调父级handleFilter以 emitsearch事件;
  2. list.tsx 的watchEffect会对dataSource逐条执行matchFilter(自定义filterOption或默认文本包含匹配),产出filteredItemsfilteredRenderItems
  3. 过滤结果驱动列表渲染与“全选”状态计算:checkStatus依据当前页可见项与选中项的关系返回'none' | 'part' | 'all',用于驱动表头复选框的半选态与全选态。

搜索框为空或过滤后无结果时,会显示notFoundContent(默认为 locale 中的“列表为空”,也支持通过#notFoundContent插槽覆盖)。

分页模式

大数据量场景下,直接给pagination传布尔值即可启用内置分页(参考 demo/pagination.vue 中 200 条数据的用例)。分页能力由 ListBody.tsx 实现:

  • 通过mergedPagination计算当前页数据(slice((current - 1) * pageSize, current * pageSize));
  • 内部复用Pagination组件,默认simple模式与size="small"pageSizeshowSizeChangershowLessItems均可通过对象形式覆盖;
  • 过滤后数据量变化时会自动校正当前页码,避免越界;
  • 分页模式下,列表头部的全选下拉菜单会额外出现“选择当前页”“反选当前页”等基于defaultListBodyRef.value.items(当前页条目)的批量操作。

注意:分页与children自定义列表互斥,且分页开启后表头不再显示默认全选勾选框,而是收敛为下拉菜单形式(checkAllCheckbox仅在非分页、非单向移除模式下渲染)。

双向绑定与移动逻辑的数据流

targetKeys是 Transfer 的状态核心,右侧列表的数据顺序严格跟随targetKeys的数组顺序。源码中watchEffect的处理逻辑如下(见 index.tsx):

  • 通过groupKeysMap(targetKeys)建立 key 到索引的映射;
  • 遍历dataSource,命中targetKeys的记录按索引填入rightDataSource的对应位置,未命中的进入leftDataSource
  • 因此左侧顺序与dataSource一致,右侧顺序与targetKeys一致,移动操作(moveTo)通过concatfilter维持这一约定。

禁用条目在移动时会被groupDisabledKeysMap过滤,无法被移动;全选操作也会通过getEnabledItemKeys跳过disabled项,避免选中不可操作的数据。

重要注意事项:key 的唯一性

按照 Vue 最新的规范,组件数组应绑定 key。在 Transfer 中,dataSource里的数据必须指定key值,组件默认将每条数据的key属性作为唯一标识。如果你的数据没有该属性,务必使用rowKey指定数据列的主键:

// 比如你的数据主键是 uid return <Transfer :rowKey="record => record.uid" />;

rowKey会在渲染前被同步执行并写入record.key,同时应用于左右两栏的数据分组与选中/移动逻辑,是自定义数据源下保证组件正确工作的关键配置。

实战示例汇总

仓库 components/transfer/demo 目录提供了完整的可运行用例,可与文档对照学习:

  • 基本用法(basic.vue):展示dataSourcetargetKeysselectedKeys双绑,以及renderchangeselectChangescroll回调的标准写法;
  • 带搜索框(search.vue):show-search+ 自定义filterOption(按description匹配)+@search事件监听;
  • 单向样式(oneway.vue):one-way模式下只能从 source 移到 target;
  • 高级用法(advanced.vue):自定义operations文案、listStyle宽高、#footer#notFoundContent插槽;
  • 自定义渲染行数据(custom-item.vue):通过#render插槽渲染复杂行内容;
  • 自定义全选文字(custom-select-all-labels.vue):selectAllLabels同时支持静态节点与函数形式(如({ selectedCount, totalCount }) => ...);
  • 分页(pagination.vue):200 条数据下直接使用pagination布尔值启用分页。

组件的自动化测试覆盖于 components/transfer/tests目录(index.test.jslist.test.jssearch.test.js),验证了禁用项不可移动、搜索过滤、全选/反选等核心行为;组件样式定义位于 components/transfer/style/index.tsx。类型定义(TransferItemTransferDirectionSelectAllLabelPaginationType等)可查阅 components/transfer/interface.ts 与 components/transfer/index.tsx。

结合本文的 API 表格、事件说明与源码级数据流解析,你可以完整掌握 Transfer 的受控状态管理、搜索过滤、分页、单向模式与自定义渲染,并将其灵活落地到实际的表单与数据挑选场景中。

【免费下载链接】ant-design-vue🌈 An enterprise-class UI components based on Ant Design and Vue. 🐜项目地址: https://gitcode.com/gh_mirrors/an/ant-design-vue

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 23:10:31

AssetRipper Unity资源提取完整指南:安装、运行到导出工程

AssetRipper Unity资源提取完整指南&#xff1a;安装、运行到导出工程 【免费下载链接】AssetRipper GUI application to analyze game files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper AssetRipper 是一个 Unity 资源提取图形界面工具&#xff1a…

作者头像 李华
网站建设 2026/9/20 23:08:02

RVC 变声器:10 分钟录音,跑通一个可换声色的语音模型

RVC 变声器&#xff1a;10 分钟录音&#xff0c;跑通一个可换声色的语音模型 【免费下载链接】Retrieval-based-Voice-Conversion-WebUI Easily train a good VC model with voice data < 10 mins! 项目地址: https://gitcode.com/GitHub_Trending/re/Retrieval-based-Voi…

作者头像 李华
网站建设 2026/9/20 23:07:56

rrvideo 使用指南:将 rrweb 会话录制(JSON)转换为视频(WebM)

前端可观测性开发工具 【免费下载链接】rrweb record and replay the web 项目地址&#xff1a; https://gitcode.com/gh_mirrors/rr/rrweb 点击查看 免费下载 rrvideo 是 rrweb 生态中一个轻量的命令行工具&#xff0c;用于把 rrweb 录制得到的会话数据&#xff08;JSON 格式…

作者头像 李华
网站建设 2026/9/20 23:05:58

Upsonic 快速上手:用 Python 构建自主 AI 智能体的完整指南

Upsonic 快速上手&#xff1a;用 Python 构建自主 AI 智能体的完整指南 【免费下载链接】gpt-computer-assistant Build autonomous AI agents in Python. 项目地址: https://gitcode.com/GitHub_Trending/gp/gpt-computer-assistant 每天早上花 40 分钟拼一份市场简报&…

作者头像 李华