vue 实现div控制多选
实现多选功能的基本思路
在Vue中实现多选功能通常涉及使用v-model绑定数组、v-for渲染选项列表,并通过点击事件管理选中状态。以下是具体实现方法:
基础实现代码示例
<template>
<div>
<div
v-for="item in items"
:key="item.id"
@click="toggleSelect(item)"
:class="{ 'selected': selectedItems.includes(item) }"
>
{{ item.name }}
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: '选项1' },
{ id: 2, name: '选项2' },
{ id: 3, name: '选项3' }
],
selectedItems: []
}
},
methods: {
toggleSelect(item) {
const index = this.selectedItems.findIndex(i => i.id === item.id);
if (index === -1) {
this.selectedItems.push(item);
} else {
this.selectedItems.splice(index, 1);
}
}
}
}
</script>
<style>
.selected {
background-color: #eee;
border: 1px solid #ccc;
}
</style>
使用复选框的优化方案
若需要更符合用户习惯的交互,可以结合复选框实现:
<template>
<div>
<div v-for="item in items" :key="item.id" class="checkbox-item">
<input
type="checkbox"
:id="'item-' + item.id"
:value="item"
v-model="selectedItems"
>
<label :for="'item-' + item.id">{{ item.name }}</label>
</div>
</div>
</template>
对象数组处理的注意事项
当选项为对象时,需确保v-model绑定的数组能正确比较对象引用。若需要根据特定属性(如id)判断选中状态,可使用计算属性:
computed: {
selectedIds() {
return this.selectedItems.map(item => item.id);
}
}
性能优化建议
对于大型列表,建议使用Set或Map存储选中状态以提高查找效率:
methods: {
toggleSelect(item) {
const selectedIds = new Set(this.selectedItems.map(i => i.id));
if (selectedIds.has(item.id)) {
this.selectedItems = this.selectedItems.filter(i => i.id !== item.id);
} else {
this.selectedItems = [...this.selectedItems, item];
}
}
}
完整组件封装示例
可封装为可复用的多选组件:
<template>
<div class="multi-select">
<div
v-for="item in options"
:key="getKey(item)"
@click="handleClick(item)"
:class="getItemClass(item)"
>
<slot :item="item" :selected="isSelected(item)">
{{ getLabel(item) }}
</slot>
</div>
</div>
</template>
<script>
export default {
props: {
options: Array,
value: Array,
itemKey: {
type: [String, Function],
default: 'id'
},
itemLabel: {
type: [String, Function],
default: 'name'
}
},
methods: {
getKey(item) {
return typeof this.itemKey === 'function'
? this.itemKey(item)
: item[this.itemKey];
},
getLabel(item) {
return typeof this.itemLabel === 'function'
? this.itemLabel(item)
: item[this.itemLabel];
},
isSelected(item) {
return this.value.some(val => this.getKey(val) === this.getKey(item));
},
handleClick(item) {
const newValue = [...this.value];
const index = newValue.findIndex(i => this.getKey(i) === this.getKey(item));
if (index > -1) {
newValue.splice(index, 1);
} else {
newValue.push(item);
}
this.$emit('input', newValue);
},
getItemClass(item) {
return {
'selected': this.isSelected(item),
'multi-select-item': true
};
}
}
}
</script>






