Skip to content

Transfer 穿梭框

代码演示

基础用法

vue
<template>
    <x-transfer
        v-model="selectedKeys"
        :data-source="listData"
        :style="{ width: '680px' }"
        show-check-all>
    </x-transfer>
</template>

<script setup>
import { ref } from 'vue'

const listData = ref([
    {
        label: 'content 1',
        value: '1',
        children: [
            { label: 'content 1-1', value: '1-1' },
            { label: 'content 1-2', value: '1-2' },
        ],
    },
    {
        label: 'content 2',
        value: '2',
        children: [
            { label: 'content 2-1', value: '2-1' },
            { label: 'content 2-2', value: '2-2' },
        ],
    },
    {
        label: 'content 3',
        value: '3',
        disabled: true,
        children: [
            { label: 'content 3-1', value: '3-1' },
            { label: 'content 3-2', value: '3-2' },
        ],
    },
    {
        label: 'content 4',
        value: '4',
        checkable: false,
        children: [
            { label: 'content 4-1', value: '4-1' },
            { label: 'content 4-2', value: '4-2' },
        ],
    },
])
const selectedKeys = ref([])
</script>

<style lang="less" scoped></style>

自定义渲染行

vue
<template>
    <x-transfer
        v-model="selectedKeys"
        :data-source="listData"
        :style="{ width: '680px' }">
        <template #item="{ record, direction }">
            <a-row
                :gutter="8"
                align="middle">
                <a-col>
                    <a-avatar></a-avatar>
                </a-col>
                <a-col>
                    <a-space
                        :size="0"
                        class="lh-1"
                        direction="vertical">
                        <a-typography-text>{{ record.label }}</a-typography-text>
                        <a-typography-text
                            class="fs-12"
                            type="secondary">
                            <template v-if="direction === 'left'">描述--左侧</template>
                            <template v-else>描述--右侧</template>
                        </a-typography-text>
                    </a-space>
                </a-col>
            </a-row>
        </template>
    </x-transfer>
</template>

<script setup>
import { ref } from 'vue'
import { nanoid } from 'nanoid'

const listData = ref(getList())
const selectedKeys = ref([])

function getList(length = 10) {
    return [...Array(length)].map(() => {
        const value = nanoid(5)
        return {
            label: value,
            value,
        }
    })
}
</script>

<style lang="less" scoped></style>

异步数据加载

vue
<template>
    <x-transfer
        ref="transferRef"
        v-model="selectedKeys"
        v-model:selected-rows="selectedRows"
        :data-source="listData"
        :load-data="onLoadData"
        :style="{ width: '680px' }"
        show-check-all>
    </x-transfer>
</template>

<script setup>
import { ref } from 'vue'
import apis from '@/apis'
import { config } from '@/config'
import { Transfer as XTransfer } from '@/components'
import { usePagination } from '@/hooks'

const selectedRows = ref([])
const selectedKeys = ref([])
const transferRef = ref()
const { paginationState, listData } = usePagination()

function onLoadData(payload) {
    const { reload } = payload || {}
    if (reload) {
        listData.value = []
    }
    transferRef.value.showLoading()
    getList()
        .then((data) => {
            transferRef.value.hideLoading()
            const { records } = data
            listData.value.push(
                ...records.map((item) => ({
                    value: item.id,
                    label: item.title,
                }))
            )
            if (listData.value.length >= 50) {
                transferRef.value.showFinished()
            }
        })
        .catch(() => {
            transferRef.value.showError()
        })
}

function getList() {
    return new Promise((resolve, reject) => {
        ;(async () => {
            const { code, data } = await apis.common
                .getPageList({
                    page: paginationState.current,
                    pageSize: paginationState.pageSize,
                })
                .catch(() => {
                    reject()
                })
            if (config('http.code.success') === code) {
                resolve(data)
            }
        })()
    })
}
</script>

<style lang="less" scoped></style>

API

Props

参数说明类型默认值
modelValue(v-model)显示在右侧框数据的 key 集合array[]
data-source数据源,非异步加载数据时,其中的部分数据将会被渲染到左边一栏中array[]
selected-rows(v-model)选中行,配合 loadData 使用。异步加载数据时需要手动回填数据,与 data-source 数据结构一致array[]
field-names自定义节点 label、value、children 的字段object{ label: 'label', value: 'value', children: 'children' }
clear-text清除按钮文本string清除
placeholder搜索框展位文本string-
show-search显示搜索booleantrue
show-check-all显示全选booleanfalse
filter-option接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 falsefunction-
locale各种语言object{ emptyText: '暂无数据' }
load-data动态加载数据函数function({keyword: string, reload: boolean})-

DataSourceType

参数说明类型默认值
label标题string number-
value唯一标识string number-
disabled禁用booleanfalse
checkable允许选择booleantrue
children子节点array-
isLeaf设置为叶子节点(设置了 loadData 时有效)booleanfalse

Events

事件名说明回调参数
change选中项发生改变modelValue

Methods

方法名说明参数返回值
showLoading显示加载中--
showFinished显示加载完成--
showError显示加载失败--

Slots

名称说明
item选项

本文档内容版权为 XYAdmin 作者所有,保留所有权利。