vue实现div多选
Vue 实现 Div 多选功能
基础实现思路
通过 Vue 的数据绑定和事件处理,可以轻松实现 div 的多选功能。核心是维护一个数组来存储选中的 div 的标识符,并通过 v-bind 和 v-on 动态更新样式和状态。
<template>
<div>
<div
v-for="item in items"
:key="item.id"
@click="toggleSelect(item.id)"
:class="{ 'selected': selectedItems.includes(item.id) }"
>
{{ item.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
],
selectedItems: []
}
},
methods: {
toggleSelect(id) {
const index = this.selectedItems.indexOf(id)
if (index === -1) {
this.selectedItems.push(id)
} else {
this.selectedItems.splice(index, 1)
}
}
}
}
</script>
<style>
.selected {
background-color: #42b983;
color: white;
}
</style>
支持 Ctrl/Shift 多选
为了实现类似桌面应用的多选体验(按住 Ctrl 或 Shift 进行多选),需要监听键盘事件并相应调整选择逻辑。
<template>
<div @keydown="handleKeyDown" @keyup="handleKeyUp" tabindex="0">
<div
v-for="(item, index) in items"
:key="item.id"
@click="handleClick(index, $event)"
:class="{ 'selected': selectedItems.includes(item.id) }"
>
{{ item.text }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' },
{ id: 3, text: 'Item 3' }
],
selectedItems: [],
lastSelectedIndex: null,
ctrlPressed: false,
shiftPressed: false
}
},
methods: {
handleKeyDown(e) {
if (e.key === 'Control') this.ctrlPressed = true
if (e.key === 'Shift') this.shiftPressed = true
},
handleKeyUp(e) {
if (e.key === 'Control') this.ctrlPressed = false
if (e.key === 'Shift') this.shiftPressed = false
},
handleClick(index, event) {
const itemId = this.items[index].id
if (this.shiftPressed && this.lastSelectedIndex !== null) {
const start = Math.min(index, this.lastSelectedIndex)
const end = Math.max(index, this.lastSelectedIndex)
this.selectedItems = []
for (let i = start; i <= end; i++) {
this.selectedItems.push(this.items[i].id)
}
} else if (this.ctrlPressed) {
const selectedIndex = this.selectedItems.indexOf(itemId)
if (selectedIndex === -1) {
this.selectedItems.push(itemId)
} else {
this.selectedItems.splice(selectedIndex, 1)
}
} else {
this.selectedItems = [itemId]
}
this.lastSelectedIndex = index
}
}
}
</script>
使用自定义指令实现
对于更复杂的交互需求,可以创建自定义指令来封装多选逻辑。
Vue.directive('multiselect', {
bind(el, binding, vnode) {
el.addEventListener('click', (e) => {
const vm = vnode.context
const item = binding.value
if (e.ctrlKey || e.metaKey) {
const index = vm.selectedItems.indexOf(item.id)
if (index === -1) {
vm.selectedItems.push(item.id)
} else {
vm.selectedItems.splice(index, 1)
}
} else {
vm.selectedItems = [item.id]
}
})
}
})
使用方式:

<div
v-for="item in items"
:key="item.id"
v-multiselect="item"
:class="{ 'selected': selectedItems.includes(item.id) }"
>
{{ item.text }}
</div>
使用第三方库
对于更高级的多选需求,可以考虑使用专门的多选库:
-
vue-multiselect:功能丰富的选择组件

npm install vue-multiselect -
v-select:基于 Vue 的下拉多选组件
npm install vue-select
这些库提供了更完善的功能,如搜索过滤、分组、远程数据加载等。
性能优化建议
当处理大量可选项时,需要注意性能优化:
- 使用虚拟滚动技术(如 vue-virtual-scroller)来渲染大量项
- 避免在模板中进行复杂的计算
- 对于大型数据集,考虑分页或懒加载
- 使用 computed 属性来处理选中状态的判断
以上方法可以根据具体需求组合使用,实现灵活高效的 div 多选功能。






