vue实现穿梭框
Vue 实现穿梭框
穿梭框(Transfer)是一种常见的 UI 组件,用于在两个列表之间移动项目。Vue 可以通过自定义组件或使用第三方库实现穿梭框功能。
自定义实现穿梭框
以下是一个简单的自定义穿梭框实现示例:
<template>
<div class="transfer-container">
<div class="transfer-list">
<h3>源列表</h3>
<ul>
<li v-for="item in sourceList" :key="item.id">
<input type="checkbox" v-model="item.selected">
{{ item.label }}
</li>
</ul>
</div>
<div class="transfer-actions">
<button @click="moveToRight">向右移动</button>
<button @click="moveToLeft">向左移动</button>
</div>
<div class="transfer-list">
<h3>目标列表</h3>
<ul>
<li v-for="item in targetList" :key="item.id">
<input type="checkbox" v-model="item.selected">
{{ item.label }}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
data() {
return {
sourceList: [
{ id: 1, label: '项目1', selected: false },
{ id: 2, label: '项目2', selected: false },
{ id: 3, label: '项目3', selected: false }
],
targetList: []
}
},
methods: {
moveToRight() {
const selectedItems = this.sourceList.filter(item => item.selected)
this.sourceList = this.sourceList.filter(item => !item.selected)
this.targetList = [...this.targetList, ...selectedItems]
},
moveToLeft() {
const selectedItems = this.targetList.filter(item => item.selected)
this.targetList = this.targetList.filter(item => !item.selected)
this.sourceList = [...this.sourceList, ...selectedItems]
}
}
}
</script>
<style>
.transfer-container {
display: flex;
justify-content: space-between;
width: 600px;
}
.transfer-list {
width: 200px;
border: 1px solid #ccc;
padding: 10px;
}
.transfer-actions {
display: flex;
flex-direction: column;
justify-content: center;
padding: 0 20px;
}
</style>
使用 Element UI 实现穿梭框
Element UI 提供了现成的 Transfer 组件,可以更快速地实现穿梭框功能:
<template>
<el-transfer
v-model="value"
:data="data"
:titles="['源列表', '目标列表']"
:button-texts="['向左移动', '向右移动']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}'
}"
@change="handleChange">
</el-transfer>
</template>
<script>
export default {
data() {
return {
data: [],
value: []
}
},
created() {
this.generateData()
},
methods: {
generateData() {
for (let i = 1; i <= 15; i++) {
this.data.push({
key: i,
label: `项目 ${i}`,
disabled: i % 4 === 0
})
}
},
handleChange(value, direction, movedKeys) {
console.log(value, direction, movedKeys)
}
}
}
</script>
使用 Ant Design Vue 实现穿梭框
Ant Design Vue 也提供了 Transfer 组件:

<template>
<a-transfer
v-model:target-keys="targetKeys"
:data-source="mockData"
:render="item => item.title"
@change="handleChange"
@selectChange="handleSelectChange"
/>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const mockData = []
for (let i = 0; i < 20; i++) {
mockData.push({
key: i.toString(),
title: `内容${i + 1}`,
description: `内容${i + 1}的描述`,
disabled: i % 3 < 1
})
}
const targetKeys = ref([])
const handleChange = (nextTargetKeys, direction, moveKeys) => {
console.log('targetKeys:', nextTargetKeys)
console.log('direction:', direction)
console.log('moveKeys:', moveKeys)
}
const handleSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
console.log('sourceSelectedKeys:', sourceSelectedKeys)
console.log('targetSelectedKeys:', targetSelectedKeys)
}
return {
mockData,
targetKeys,
handleChange,
handleSelectChange
}
}
}
</script>
实现功能要点
- 数据管理:维护两个数组分别存储源列表和目标列表的数据
- 选择功能:通过复选框或点击事件实现项目选择
- 移动逻辑:根据选择状态将项目从一个列表移动到另一个列表
- 样式设计:合理安排布局,确保用户体验良好
自定义实现提供了最大的灵活性,但需要处理更多细节。使用 UI 框架的组件可以快速实现功能,但可能受限于框架提供的功能和样式。根据项目需求选择合适的方式。






