Transfer 穿梭框 ​

双栏穿梭选择框,数据在左(源)右(目标)两个列表之间移动。

基础用法 ​

基础穿梭框 ​

Transfer 的数据通过 data 属性传入。 数据需要是一个对象数组,每个对象有以下属性:key 为数据的唯一性标识,label 为显示文本,disabled 表示该项数据是否禁止被操作。 目标列表中的数据项会同步到绑定至 v-model 的变量,值为数据项的 key 所组成的数组。 当然,如果希望在初始状态时目标列表不为空,可以像本例一样为 v-model 绑定的变量赋予一个初始值。

无数据

自定义 ​

可以对列表标题文案、按钮文案、数据项的渲染函数、列表顶部的勾选状态文案、列表底部的内容区等进行自定义。 使用 titles、button-texts、render-content 和 format 属性分别对列表标题文案、按钮文案、数据项的渲染函数和列表顶部的勾选状态文案进行自定义。 数据项的渲染还可以使用 default 作用域插槽进行自定义。 对于列表底部的内容区,提供了两个具名插槽:left-footer 和 right-footer。 此外,如果希望某些数据项在初始化时就被勾选,可以使用 left-default-checked 和 right-default-checked 属性。 最后,本例还展示了 change 事件的用法。 注意,由于 JSFiddle 不支持 JSX 语法,故该示例无法在 JSFiddle 运行。 但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。

通过 render-content 自定义数据项

通过 scoped slot 自定义数据项

数据项属性别名 ​

默认情况下,Transfer 仅能识别数据项中的 key、label 和 disabled 字段。 如果你的数据的字段名不同,可以使用 props 属性为它们设置别名。 本例中的数据源没有 key 和 label 字段,在功能上与它们相同的字段名为 value 和 desc。 因此可以使用 props 属性为 key 和 label 设置别名。

无数据

自定义空内容 ​

使用 left-empty 和 right-empty 插槽来自定义每个面板在列表为空或未找到筛选结果时显示的内容。

暂无数据

功能 ​

可搜索过滤 ​

在数据很多的情况下,可以对数据进行搜索和过滤。 设置 filterable 为 true 即可开启搜索模式。 默认情况下,若数据项的 label 属性包含搜索关键字,则会在搜索结果中显示。 你也可以使用 filter-method 定义自己的搜索逻辑。 filter-method 接收一个方法,当搜索关键字变化时,会将当前的关键字、每个数据项以及该数据项所属面板(left / right)传给该方法。 若方法返回 true,则会在搜索结果中显示对应的数据项。

无数据

分页与面板尺寸 ​

通过 show-pagination 属性设置是否开启分页功能,page-size 控制每页条数。 通过 panel-width 属性设置 Transfer 左右面板的宽度,panel-height 属性设置面板高度。 列表顶部的勾选状态文案还可以通过 render-checked 渲染函数完全自定义,其入参为 (checked, total, panelType)。

1/7

无数据

单向穿梭框 1.3.4 ​

设置 one-way 为 true 即可开启单向模式,只允许「左 → 右」移动,适用于一次性的选择场景。 该模式下右侧列表项以纯文本展示,每项尾部有 × 按钮,点击 × 即可把该项移回左侧。

列表 23 项

心血管内科(文字超出显示)
神经外科
骨科

简单模式 1.3.4 ​

设置 simple 为 true 即可开启简单模式,隐藏中间的穿梭按钮,直接单击列表项完成移动。 该模式下左右列表项均以文本行展示:左侧整行可点,单击即右移;右侧点击 × 即左移。 禁用项(数据自带 disabled 或命中 disabled-right)不可移动,也不显示 ×。

列表 110 项

便常规
肝功能
肾功能
空腹血糖
血脂
电解质
凝血功能
血沉
C 反应蛋白
降钙素原

列表 22 项

血常规
尿常规

简单模式下没有中间的穿梭按钮,单击列表项即可移动。

禁用右侧数据项 1.3.4 ​

通过 disabled-right 传入一个 key 数组,命中的右侧列表项将被禁用(不可勾选、不可删除、不可点击移动),其效果与数据项自带的 disabled 字段等效叠加。 该属性只作用于右侧列表,左侧列表的行为不受影响。 单向 / 简单模式及 target-clearable 下,被禁用的项也不会出现 ×。

带选择器的穿梭框 1.3.4 ​

设置 selectable 为 true 后,左右列表顶部都会显示一个可清空的单选下拉框,可按所属分组快速筛选。 选项由数据源按 parentKey 去重后的 parentLabel 生成,左右面板的筛选相互独立。 选中某个分组后,该面板列表只保留 parentKey 命中的项;该筛选与 filterable 的关键字过滤相互独立,两者同时生效时取交集。 开启该模式后,数据源中的每一项都必须带有 parentKey 与 parentLabel 字段,否则会抛出异常提示。

请输入搜索内容

请输入搜索内容

虚拟滚动 1.3.4 ​

大数据量时仅展示可视区域内的条目。

设置 virtual-scroll 为 true 即可开启虚拟滚动。 可通过 item-size 自定义条目高度,默认 32(与主题变量 --w3-transfer-item-height 一致)。 可与 filterable 搭配使用,过滤后滚动位置自动复位到顶部。

无数据

列表区扩展 ​

树型穿梭框 1.3.4 ​

source / target 插槽用于整体替换面板的列表区(原复选框列表不再显示),适合树型、表格型等自定义外壳的场景。

插槽参数:

  • data:经过搜索过滤后的当前面板数据
  • selectedKeys:当前已勾选的 key 数组
  • onSelect(cur, { checkedKeys }):回写勾选结果,签名与 w-tree 的 check 事件一致,可直接绑定

树型场景通常只需要替换左侧,右侧保持默认列表。本例设置 check-strictly(父子不关联):

  • 父、子节点都是独立的数据项,data 中两者都包含,勾选互不影响
  • 父节点也可以单独勾选、单独穿梭到右侧
  • 已穿梭到右侧的节点(无论父或子)在左侧树中禁用,移回后自动恢复,避免重复穿梭

搜索过滤由业务接管:通过 left-search 事件拿到关键字后调用树自身的 filter 方法,插槽内树的数据完全由业务掌握。

用 source 插槽把左侧列表区整体替换为 w-tree,右侧保持默认列表。

内科
心血管内科
呼吸内科
消化内科(默认禁用)
外科
普通外科
骨科

树型穿梭框(父子关联) 1.3.4 ​

与上一例的区别有两点。

一是勾选联动:不设置 check-strictly,勾选父节点会联动勾选其全部子节点,onSelect 收到的 checkedKeys 就是树组件计算后的完整集合。

二是 data 的取舍:父节点能否穿梭到右侧由 data 决定,与勾选联动无关——父子关联场景下父节点只作分组容器,data 只提供叶子节点,父节点不会出现在右侧;若业务需要父节点也参与穿梭,把它一并放进 data 即可。

树本身由插槽参数 data(当前源列表数据)重建:

  • 仍在源列表中的叶子正常可选
  • 已穿梭到右侧的叶子禁用,联动勾选父节点时也不会被计入 checkedKeys
  • 从右侧移回后对应节点自动恢复可选

不设置 check-strictly 的父子关联形态:勾选父节点联动勾选全部子节点,data 只提供叶子节点。

总院
内科楼
外科楼
南院区
门诊楼
医技楼

表格型穿梭框 1.3.4 ​

show-table 配合 source / target 插槽,把左右两个面板的列表区整体替换为 w-table(列表以表格形态呈现时,头部的全选复选框与勾选计数已无意义)。

设置 show-table 为 true 后:

  • 面板头部只显示数据项数量(如 12 项),不显示全选复选框与勾选计数
  • 头部标题区可通过 left-header-title / right-header-title 插槽自定义(本例左侧为「医嘱(共 12 条)」)
  • 列表区的上下内边距归零,表格可贴边填充

表格的 select-all / selection-change 回传的是行对象数组,需要转换后调用 onSelect(null, { checkedKeys })。注意 source / target 与逐项自定义的 default 插槽是两个不同层级:前者替换整个列表区,后者只替换单个数据项的内容,二者不可混用。

左右列表区均替换为 w-table,头部只显示数据项数量,通过 selection-change 回写勾选结果。

医嘱(共 12 条) 10 项

列表 22 项

事件处理器要写成函数表达式

@selection-change="handleSelect(onSelect)" 这类只做调用、不使用 $event 的写法会被 Vue3 编译为行内语句($event => handleSelect(onSelect)),返回值被丢弃,勾选结果不会回写。 请改成 @selection-change="handleSelect($event, onSelect)" 或箭头函数 @selection-change="(rows) => ..."。

Transfer API ​

Attributes ​

参数说明类型默认值
model-value / v-model选中项绑定值object[]
dataTransfer 的数据源object[]
filterable是否可搜索booleanfalse
filter-placeholder搜索框占位符string—
filter-method自定义搜索方法,第三个参数为当前面板归属Function—
target-order右侧列表元素的排序策略: 若为 original,则保持与数据源相同的顺序; 若为 push,则新加入的元素排在最后; 若为 unshift,则新加入的元素排在最前enumoriginal
titles自定义列表标题object[]
button-texts自定义按钮文案object[]
render-content自定义数据项渲染函数object—
format列表顶部勾选状态文案object{}
props数据源的字段别名object—
left-default-checked初始状态下左侧列表的已勾选项的 key 数组object[]
right-default-checked初始状态下右侧列表的已勾选项的 key 数组object[]
validate-event是否触发表单验证booleantrue
show-pagination是否显示分页booleanfalse
page-size每页显示条数number10
panel-width自定义面板宽度array['200px', '200px']
panel-height自定义面板高度string'278px'
render-checked左、右列表顶部的勾选状态文案渲染 Function,返回的字符串按 HTML 渲染Function—
one-way 1.3.4是否为单向模式。开启后仅允许「左 → 右」移动,右侧条目以纯文本展示,可通过 × 单项移除booleanfalse
simple 1.3.4是否为简单模式。开启后隐藏中间按钮区,列表项单击即移动booleanfalse
target-clearable 1.3.4右侧列表项悬浮时是否在尾部显示 × 删除按钮booleanfalse
selectable 1.3.4是否在列表顶部显示按 parentKey 过滤的下拉选择器,左右面板各自独立筛选。开启后数据项必须包含 parentKey 与 parentLabel,否则抛出异常booleanfalse
show-table 1.3.4是否为表格模式。开启后面板头部只显示数据项数量;表格本体需业务通过 source / target 插槽自行提供booleanfalse
disabled-right 1.3.4右侧列表中需要禁用的项的 key 数组,与数据项自带的 disabled 等效叠加。只作用于右侧列表object[]
virtual-scroll 1.3.4是否开启虚拟滚动,大数据量时仅展示可视区域内的条目booleanfalse
item-size 1.3.4虚拟滚动的条目高度,与主题变量 --w3-transfer-item-height 保持一致number32

Events ​

事件名说明类型
change右侧列表元素变化时触发Function
left-check-change左侧列表元素被用户选中 / 取消选中时触发Function
right-check-change右侧列表元素被用户选中 / 取消选中时触发Function
left-page-change左侧列表分页变化时触发Function
right-page-change右侧列表分页变化时触发Function
left-search 1.3.4左侧列表搜索框每输入一个字符时触发,值为当前输入Function
right-search 1.3.4右侧列表搜索框每输入一个字符时触发,值为当前输入Function

Slots ​

插槽名说明
default自定义单个数据项的内容,参数为 { option }
left-footer左侧列表底部的内容
right-footer右侧列表底部的内容
left-empty左侧面板为空或没有数据符合筛选条件时的内容
right-empty右侧面板为空或没有数据符合筛选条件时的内容
left-header-title 1.3.4左侧面板头部标题区内容
right-header-title 1.3.4右侧面板头部标题区内容
source 1.3.4整列表区替换左侧面板的列表区,参数为 { data, selectedKeys, onSelect }
target 1.3.4整列表区替换右侧面板的列表区,参数为 { data, selectedKeys, onSelect }

请注意 source / target 与 default 是两个不同的层级

  • default 只自定义单个数据项的内容,列表区(含复选框、滚动容器)仍由组件提供;
  • source / target 替换整个列表区,用于树型、表格型等自定义外壳的场景,此时列表区完全由插槽内容提供;
  • 两者都仅在提供对应插槽时才生效,未提供时列表区 DOM 与不提供时完全一致。

插槽参数说明:data 为搜索过滤后的当前面板数据;selectedKeys 为当前已勾选的 key 数组;onSelect(cur, { checkedKeys }) 用于回写勾选状态,其签名与 w-tree 的 check 事件一致,可直接绑定。

Exposes ​

名称说明类型
clearQuery清空某个面板的搜索关键词Function
leftPanel左侧面板 refobject
rightPanel右侧面板 refobject

Transfer Panel API ​

Exposes ​

名称描述类型
query过滤关键词string
selectQuery选择器的过滤关键词string
selectOptions选择器去重后的选项列表object

Type Declarations ​

Show declarations
ts
import type { h as H, VNode } from 'vue'

type TransferKey = string | number

type TransferDirection = 'left' | 'right'

type TransferDataItem = Record<string, any>

type renderContent = (h: typeof H, option: TransferDataItem) => VNode | VNode[]

interface TransferFormat {
  noChecked?: string
  hasChecked?: string
}

interface TransferPropsAlias {
  label?: string
  key?: string
  disabled?: string
}

Copyright 2025 Winning Health 版权所有