vue实现左右穿梭框
实现左右穿梭框的基本思路
穿梭框(Transfer)是常见的UI组件,用于在左右两个列表之间移动数据项。Vue中可以通过组件化方式实现,核心逻辑包括数据绑定、列表渲染和移动操作。
数据结构设计
通常需要维护以下数据:
- 左侧列表数据源
- 右侧列表数据源
- 选中的项目集合
data() {
return {
leftItems: [
{ id: 1, label: '选项1' },
{ id: 2, label: '选项2' },
{ id: 3, label: '选项3' }
],
rightItems: [],
leftSelected: [],
rightSelected: []
}
}
组件模板结构
<div class="transfer-container">
<div class="list-box">
<h4>可选列表</h4>
<ul>
<li v-for="item in leftItems"
:key="item.id"
@click="toggleLeftSelection(item)">
{{ item.label }}
</li>
</ul>
</div>
<div class="action-buttons">
<button @click="moveToRight">>></button>
<button @click="moveToLeft"><<</button>
</div>
<div class="list-box">
<h4>已选列表</h4>
<ul>
<li v-for="item in rightItems"
:key="item.id"
@click="toggleRightSelection(item)">
{{ item.label }}
</li>
</ul>
</div>
</div>
核心方法实现
选择项目逻辑:
methods: {
toggleLeftSelection(item) {
const index = this.leftSelected.findIndex(i => i.id === item.id)
if (index > -1) {
this.leftSelected.splice(index, 1)
} else {
this.leftSelected.push(item)
}
},
toggleRightSelection(item) {
const index = this.rightSelected.findIndex(i => i.id === item.id)
if (index > -1) {
this.rightSelected.splice(index, 1)
} else {
this.rightSelected.push(item)
}
}
}
项目移动逻辑:
moveToRight() {
this.rightItems = [...this.rightItems, ...this.leftSelected]
this.leftItems = this.leftItems.filter(
item => !this.leftSelected.some(sel => sel.id === item.id)
)
this.leftSelected = []
},
moveToLeft() {
this.leftItems = [...this.leftItems, ...this.rightSelected]
this.rightItems = this.rightItems.filter(
item => !this.rightSelected.some(sel => sel.id === item.id)
)
this.rightSelected = []
}
样式优化建议
.transfer-container {
display: flex;
align-items: center;
gap: 20px;
}
.list-box {
border: 1px solid #ddd;
width: 200px;
height: 300px;
overflow-y: auto;
}
.list-box ul {
list-style: none;
padding: 0;
margin: 0;
}
.list-box li {
padding: 8px 12px;
cursor: pointer;
}
.list-box li:hover {
background-color: #f5f5f5;
}
.action-buttons {
display: flex;
flex-direction: column;
gap: 10px;
}
进阶功能扩展
-
搜索过滤功能:
<input v-model="leftFilter" placeholder="搜索可选列表"> <input v-model="rightFilter" placeholder="搜索已选列表"> -
全选/全不选功能:
selectAllLeft() { this.leftSelected = [...this.leftItems] } -
拖拽排序支持:
<li draggable="true" @dragstart="handleDragStart(item)" @drop="handleDrop($event, 'left')" @dragover.prevent>
使用现成组件库
如需快速实现,可以考虑:
- Element UI 的
<el-transfer> - Ant Design Vue 的
<a-transfer> - Vuetify 的
<v-combobox>多选模式
这些组件库提供了更完善的穿梭框实现,包含搜索、全选、自定义渲染等高级功能。







