vue实现multiselect效果
Vue 实现多选(Multiselect)效果
使用第三方库 vue-multiselect
安装依赖包:
npm install vue-multiselect
基础实现代码:
<template>
<div>
<multiselect
v-model="selected"
:options="options"
:multiple="true"
:close-on-select="false"
placeholder="选择项"
label="name"
track-by="name"
></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
data() {
return {
selected: [],
options: [
{ name: '选项1' },
{ name: '选项2' },
{ name: '选项3' }
]
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
自定义实现多选组件
基础HTML结构:
<template>
<div class="custom-multiselect">
<div class="selected-items">
<span v-for="(item, index) in selected" :key="index">
{{ item }}
<button @click="removeItem(index)">×</button>
</span>
</div>
<input
type="text"
v-model="search"
@focus="showOptions = true"
@blur="handleBlur"
@keydown.enter="addItem"
/>
<ul v-show="showOptions">
<li
v-for="(option, index) in filteredOptions"
:key="index"
@mousedown="selectItem(option)"
>
{{ option }}
</li>
</ul>
</div>
</template>
JavaScript逻辑:
<script>
export default {
data() {
return {
selected: [],
options: ['选项1', '选项2', '选项3', '选项4'],
search: '',
showOptions: false
}
},
computed: {
filteredOptions() {
return this.options.filter(option =>
option.toLowerCase().includes(this.search.toLowerCase()) &&
!this.selected.includes(option)
)
}
},
methods: {
selectItem(item) {
if (!this.selected.includes(item)) {
this.selected.push(item)
}
this.search = ''
this.showOptions = false
},
removeItem(index) {
this.selected.splice(index, 1)
},
addItem() {
if (this.search && !this.selected.includes(this.search)) {
this.selected.push(this.search)
this.search = ''
}
},
handleBlur() {
setTimeout(() => {
this.showOptions = false
}, 200)
}
}
}
</script>
基础样式:
.custom-multiselect {
position: relative;
width: 300px;
}
.selected-items {
display: flex;
flex-wrap: wrap;
gap: 5px;
margin-bottom: 5px;
}
.selected-items span {
background: #eee;
padding: 2px 5px;
border-radius: 3px;
display: flex;
align-items: center;
}
.selected-items button {
margin-left: 5px;
background: none;
border: none;
cursor: pointer;
}
input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
ul {
position: absolute;
width: 100%;
margin: 0;
padding: 0;
list-style: none;
background: white;
border: 1px solid #ddd;
max-height: 200px;
overflow-y: auto;
z-index: 100;
}
li {
padding: 8px;
cursor: pointer;
}
li:hover {
background: #f5f5f5;
}
功能增强建议
添加搜索高亮功能:
// 在methods中添加
highlightText(text) {
if (!this.search) return text
const regex = new RegExp(this.search, 'gi')
return text.replace(regex, match => `<span class="highlight">${match}</span>`)
}
添加分组支持:
options: [
{
group: '水果',
items: ['苹果', '香蕉', '橙子']
},
{
group: '蔬菜',
items: ['胡萝卜', '番茄', '黄瓜']
}
]
添加远程搜索功能:
async searchItems(query) {
if (query.length < 2) return
const response = await axios.get('/api/search', { params: { q: query } })
this.options = response.data
}






