#穿梭框 (Transfer)
穿梭框组件,用于在两个列表之间移动数据。
#组件特性
- 🔄 数据穿梭:在源列表和目标列表之间无缝移动数据。
- 🔍 搜索过滤:内置搜索功能,方便在大量数据中快速查找。
- 🖱️ 拖拽排序:支持对已选择的目标列表项进行拖拽排序。
- 📝 表单集成:完美支持与
BrForm结合使用,实现表单校验。 - 🎨 高度定制:提供丰富的插槽支持自定义渲染,支持主题定制。
#基础用法
最基本的用法。你需要提供 data 作为数据源,并使用 v-model 绑定已选择的项的 key。
<script setup lang="ts">
import { ref } from 'vue'
import { BrTransfer } from '@breezeui/vue'
const generateData = (count = 15) => {
return Array.from({ length: count }).map((_, i) => ({
key: i,
label: `Item ${i + 1}`,
desc: `Description for item ${i + 1}`,
disabled: i % 5 === 0,
}))
}
const data = ref(generateData())
const value = ref([1, 4])
</script>
<template>
<BrTransfer
v-model="value"
:data="data"
:titles="['Source List', 'Target List']"
/>
</template>#搜索与拖拽排序
通过设置 filterable 开启搜索功能。通过设置 draggable 开启目标列表的拖拽排序功能。
<script setup lang="ts">
import { ref } from 'vue'
import { BrTransfer } from '@breezeui/vue'
const generateData = (count = 20) => {
return Array.from({ length: count }).map((_, i) => ({
key: i,
label: `Item ${i + 1}`,
desc: `Description for item ${i + 1}`,
disabled: i % 5 === 0,
}))
}
const data = ref(generateData())
const value = ref([2, 5])
</script>
<template>
<BrTransfer
v-model="value"
:data="data"
filterable
draggable
:titles="['Available', 'Selected (Draggable)']"
filter-placeholder="Type to search..."
>
<template #option="{ item }">
<div class="flex flex-col">
<span class="font-medium">{{ item.label }}</span>
<span class="text-xs text-muted-foreground">{{ item.desc }}</span>
</div>
</template>
</BrTransfer>
</template>#表单集成
BrTransfer 可以与 BrForm 无缝集成,实现表单验证。
<script setup lang="ts">
import { ref } from 'vue'
import { BrTransfer, BrForm, BrFormItem, BrButton } from '@breezeui/vue'
const formData = ref({
roles: []
})
const rolesData = ref([
{ key: 'admin', label: 'Admin (Admin)' },
{ key: 'editor', label: 'Editor (Editor)' },
{ key: 'viewer', label: 'Viewer (Viewer)' },
{ key: 'guest', label: 'Guest (Guest)' },
])
const handleSubmit = (values: any) => {
alert(JSON.stringify(formData.value))
}
const handleInvalidSubmit = (errors: any) => {
console.error('Form validation failed:', errors)
}
</script>
<template>
<BrForm @submit="handleSubmit" @invalid-submit="handleInvalidSubmit">
<BrFormItem
name="roles"
label="Assign Roles"
required
:rules="(val: any[]) => {
if (!val || val.length === 0) return 'Please select at least one role'
if (val.length < 2) return 'Select at least 2 roles for security'
return true
}"
>
<BrTransfer
v-model="formData.roles"
:data="rolesData"
:titles="['Roles', 'Assigned']"
target-order="push"
/>
</BrFormItem>
<BrButton type="submit" class="mt-4">Submit Form</BrButton>
</BrForm>
</template>#主题定制
使用 BrConfigProvider 可以轻松自定义组件的主题颜色和圆角。
<script setup lang="ts">
import { ref } from 'vue'
import { BrTransfer, BrConfigProvider } from '@breezeui/vue'
const generateData = (count = 5) => {
return Array.from({ length: count }).map((_, i) => ({
key: i,
label: `Item ${i + 1}`,
}))
}
const data = ref(generateData())
const value = ref([2])
</script>
<template>
<BrConfigProvider
:theme="{
primary: '280 84% 67%',
radius: '1rem',
}"
>
<div class="p-6 border rounded-2xl bg-card shadow-sm">
<h3 class="mb-4 font-medium text-primary">Custom Primary Color & Radius</h3>
<BrTransfer
v-model="value"
:data="data"
:titles="['Theme Left', 'Theme Right']"
/>
</div>
</BrConfigProvider>
</template>#API
#Transfer 属性 (Props)
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue / v-model | (string | number)[] | [] | 绑定值,表示已选择的项 |
data | TransferDataItem[] | [] | 数据源 |
filterable | boolean | false | 是否开启搜索 |
filterPlaceholder | string | 'Search here' | 搜索框占位符 |
filterMethod | (query: string, item: TransferDataItem) => boolean | - | 自定义搜索方法 |
titles | [string, string] | ['Source', 'Target'] | 左右面板的标题 |
buttonTexts | [string, string] | ['', ''] | 左右按钮的文本 |
draggable | boolean | false | 是否允许拖拽目标面板的项进行排序 |
targetOrder | 'original' | 'push' | 'unshift' | 'original' | 目标面板的数据排序策略 |
size | 'sm' | 'md' | 'lg' | 'md' | 穿梭框尺寸 |
disabled | boolean | false | 是否禁用 |
emptyText | string | 'No data' | 数据为空时的文本 |
#TransferDataItem 数据结构
| 属性名 | 类型 | 说明 |
|---|---|---|
key | string | number | 唯一标识符 |
label | string | 显示文本 |
disabled | boolean | 是否禁用该项 |
[key: string] | any | 其他自定义属性 |
#Transfer 事件 (Emits)
| 事件名 | 参数 | 说明 |
|---|---|---|
update:modelValue | (value: (string | number)[]) | 绑定值改变时触发 |
change | (value: (string | number)[], direction: 'left' | 'right', movedKeys: (string | number)[]) | 选项在两边移动时触发 |
search | (query: string, direction: 'left' | 'right') | 搜索内容改变时触发 |
left-check-change | (checkedKeys: (string | number)[], checkedNodes: TransferDataItem[]) | 左侧面板选中项改变时触发 |
right-check-change | (checkedKeys: (string | number)[], checkedNodes: TransferDataItem[]) | 右侧面板选中项改变时触发 |
#Transfer 插槽 (Slots)
| 插槽名 | 说明 |
|---|---|
option | 自定义数据项的内容 |
leftEmpty | 左侧面板无数据时的内容 |
rightEmpty | 右侧面板无数据时的内容 |
leftFooter | 左侧面板的底部内容 |
rightFooter | 右侧面板的底部内容 |