Transfer 穿梭框

基础用法

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

Transfer 穿梭框 - 图1

  1. <template>
  2. <el-transfer v-model="value" :data="data" />
  3. </template>
  4. <script lang="ts" setup>
  5. import { ref } from 'vue'
  6. interface Option {
  7. key: number
  8. label: string
  9. disabled: boolean
  10. }
  11. const generateData = () => {
  12. const data: Option[] = []
  13. for (let i = 1; i <= 15; i++) {
  14. data.push({
  15. key: i,
  16. label: `Option ${i}`,
  17. disabled: i % 4 === 0,
  18. })
  19. }
  20. return data
  21. }
  22. const data = ref<Option[]>(generateData())
  23. const value = ref([])
  24. </script>

可搜索过滤

在数据很多的情况下,可以对数据进行搜索和过滤。

设置 filterabletrue 即可开启搜索模式。 默认情况下,若数据项的 label 属性包含搜索关键字,则会在搜索结果中显示。 你也可以使用 filter-method 定义自己的搜索逻辑。 filter-method 接收一个方法,当搜索关键字变化时,会将当前的关键字和每个数据项传给该方法。 若方法返回 true,则会在搜索结果中显示对应的数据项。

Transfer 穿梭框 - 图2

  1. <template>
  2. <el-transfer
  3. v-model="value"
  4. filterable
  5. :filter-method="filterMethod"
  6. filter-placeholder="State Abbreviations"
  7. :data="data"
  8. />
  9. </template>
  10. <script lang="ts" setup>
  11. import { ref } from 'vue'
  12. interface Option {
  13. key: number
  14. label: string
  15. initial: string
  16. }
  17. const generateData = () => {
  18. const data: Option[] = []
  19. const states = [
  20. 'California',
  21. 'Illinois',
  22. 'Maryland',
  23. 'Texas',
  24. 'Florida',
  25. 'Colorado',
  26. 'Connecticut ',
  27. ]
  28. const initials = ['CA', 'IL', 'MD', 'TX', 'FL', 'CO', 'CT']
  29. states.forEach((city, index) => {
  30. data.push({
  31. label: city,
  32. key: index,
  33. initial: initials[index],
  34. })
  35. })
  36. return data
  37. }
  38. const data = ref<Option[]>(generateData())
  39. const value = ref([])
  40. const filterMethod = (query, item) => {
  41. return item.initial.toLowerCase().includes(query.toLowerCase())
  42. }
  43. </script>

自定义

可以对列表标题文案、按钮文案、数据项的渲染函数、列表底部的勾选状态文案、列表底部的内容区等进行自定义。

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

Transfer 穿梭框 - 图3

  1. <template>
  2. <p style="text-align: center; margin: 0 0 20px">
  3. Customize data items using render-content
  4. </p>
  5. <div style="text-align: center">
  6. <el-transfer
  7. v-model="leftValue"
  8. style="text-align: left; display: inline-block"
  9. filterable
  10. :left-default-checked="[2, 3]"
  11. :right-default-checked="[1]"
  12. :render-content="renderFunc"
  13. :titles="['Source', 'Target']"
  14. :button-texts="['To left', 'To right']"
  15. :format="{
  16. noChecked: '${total}',
  17. hasChecked: '${checked}/${total}',
  18. }"
  19. :data="data"
  20. @change="handleChange"
  21. >
  22. <template #left-footer>
  23. <el-button class="transfer-footer" size="small">Operation</el-button>
  24. </template>
  25. <template #right-footer>
  26. <el-button class="transfer-footer" size="small">Operation</el-button>
  27. </template>
  28. </el-transfer>
  29. <p style="text-align: center; margin: 50px 0 20px">
  30. Customize data items using scoped slot
  31. </p>
  32. <div style="text-align: center">
  33. <el-transfer
  34. v-model="rightValue"
  35. style="text-align: left; display: inline-block"
  36. filterable
  37. :left-default-checked="[2, 3]"
  38. :right-default-checked="[1]"
  39. :titles="['Source', 'Target']"
  40. :button-texts="['To left', 'To right']"
  41. :format="{
  42. noChecked: '${total}',
  43. hasChecked: '${checked}/${total}',
  44. }"
  45. :data="data"
  46. @change="handleChange"
  47. >
  48. <template #default="{ option }">
  49. <span>{{ option.key }} - {{ option.label }}</span>
  50. </template>
  51. <template #left-footer>
  52. <el-button class="transfer-footer" size="small">Operation</el-button>
  53. </template>
  54. <template #right-footer>
  55. <el-button class="transfer-footer" size="small">Operation</el-button>
  56. </template>
  57. </el-transfer>
  58. </div>
  59. </div>
  60. </template>
  61. <script lang="ts" setup>
  62. import { ref } from 'vue'
  63. import type { VNode, VNodeProps } from 'vue'
  64. interface Option {
  65. key: number
  66. label: string
  67. disabled: boolean
  68. }
  69. const generateData = (): Option[] => {
  70. const data: Option[] = []
  71. for (let i = 1; i <= 15; i++) {
  72. data.push({
  73. key: i,
  74. label: `Option ${i}`,
  75. disabled: i % 4 === 0,
  76. })
  77. }
  78. return data
  79. }
  80. const data = ref(generateData())
  81. const rightValue = ref([1])
  82. const leftValue = ref([1])
  83. const renderFunc = (
  84. h: (type: string, props: VNodeProps | null, children?: string) => VNode,
  85. option: Option
  86. ) => {
  87. return h('span', null, option.label)
  88. }
  89. const handleChange = (
  90. value: number | string,
  91. direction: 'left' | 'right',
  92. movedKeys: string[] | number[]
  93. ) => {
  94. console.log(value, direction, movedKeys)
  95. }
  96. </script>
  97. <style>
  98. .transfer-footer {
  99. margin-left: 15px;
  100. padding: 6px 5px;
  101. }
  102. </style>

数据项属性别名

默认情况下,Transfer 仅能识别数据项中的 keylabeldisabled 字段。 如果你的数据的字段名不同,可以使用 props 属性为它们设置别名。

本例中的数据源没有 keylabel 字段,在功能上与它们相同的字段名为 valuedesc。 因此可以使用props 属性为 keylabel 设置别名。

Transfer 穿梭框 - 图4

  1. <template>
  2. <el-transfer
  3. v-model="value"
  4. :props="{
  5. key: 'value',
  6. label: 'desc',
  7. }"
  8. :data="data"
  9. />
  10. </template>
  11. <script lang="ts" setup>
  12. import { ref } from 'vue'
  13. interface Option {
  14. value: number
  15. desc: string
  16. disabled: boolean
  17. }
  18. const generateData = () => {
  19. const data: Option[] = []
  20. for (let i = 1; i <= 15; i++) {
  21. data.push({
  22. value: i,
  23. desc: `Option ${i}`,
  24. disabled: i % 4 === 0,
  25. })
  26. }
  27. return data
  28. }
  29. const data = ref<Option[]>(generateData())
  30. const value = ref([])
  31. </script>

属性

属性说明类型可选值默认值
model-value / v-model选中项绑定值array
dataTransfer 的数据源array[{ key, label, disabled }][ ]
filterable是否可搜索booleanfalse
filter-placeholder搜索框占位符stringEnter keyword
filter-method自定义搜索方法function
target-order右侧列表元素的排序策略: 若为 original,则保持与数据源相同的顺序; 若为 push,则新加入的元素排在最后; 若为 unshift,则新加入的元素排在最前stringoriginal / push / unshiftoriginal
titles自定义列表标题array[‘List 1’, ‘List 2’]
button-texts自定义按钮文案array[ ]
render-content自定义数据项渲染函数function(h, option)
format列表顶部勾选状态文案object{noChecked, hasChecked}{ noChecked: ‘${checked}/${total}’, hasChecked: ‘${checked}/${total}’ }
props数据源的字段别名object{key, label, disabled}
left-default-checked初始状态下左侧列表的已勾选项的 key 数组array[ ]
right-default-checked初始状态下右侧列表的已勾选项的 key 数组array[ ]
validate-event是否触发表单验证boolean-true

插槽

插槽名说明
自定义数据项的内容, 参数为 { option }
left-footer左侧列表底部的内容
right-footer右侧列表底部的内容

方法

方法名说明参数
clearQuery清空某个面板的搜索关键词‘left’ / ‘right’

事件

事件名说明回调参数
change右侧列表元素变化时触发当前值、数据移动的方向(’left’ / ‘right’)、发生移动的数据 key 数组
left-check-change左侧列表元素被用户选中 / 取消选中时触发当前被选中的元素的 key 数组、选中状态发生变化的元素的 key 数组
right-check-change右侧列表元素被用户选中 / 取消选中时触发当前被选中的元素的 key 数组、选中状态发生变化的元素的 key 数组

源代码

组件 Transfer 穿梭框 - 图5 文档 Transfer 穿梭框 - 图6

贡献者

Transfer 穿梭框 - 图7 云游君

Transfer 穿梭框 - 图8 三咲智子

Transfer 穿梭框 - 图9 jeremywu

Transfer 穿梭框 - 图10 zz

Transfer 穿梭框 - 图11 LIUCHAO

Transfer 穿梭框 - 图12 Delyan Haralanov

Transfer 穿梭框 - 图13 msidolphin

Transfer 穿梭框 - 图14 Aex

Transfer 穿梭框 - 图15 Zong

Transfer 穿梭框 - 图16 Hefty

Transfer 穿梭框 - 图17 bqy

Transfer 穿梭框 - 图18 btea

Transfer 穿梭框 - 图19 Alan Wang

Transfer 穿梭框 - 图20 kooriookami

Transfer 穿梭框 - 图21 Bios Sun

Transfer 穿梭框 - 图22 on the field of hope

Transfer 穿梭框 - 图23 zazzaz

Transfer 穿梭框 - 图24 Hades-li

Transfer 穿梭框 - 图25 C.Y.Kun

Transfer 穿梭框 - 图26 qiang