vue实现下拉组件
基础下拉组件实现
使用Vue的v-model和事件绑定实现基础下拉功能。核心是通过v-show或v-if控制下拉菜单的显示状态。
<template>
<div class="dropdown">
<button @click="toggleDropdown">{{ selectedOption || 'Select' }}</button>
<ul v-show="isOpen">
<li
v-for="option in options"
:key="option.value"
@click="selectOption(option)"
>
{{ option.label }}
</li>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false,
selectedOption: null,
options: [
{ value: '1', label: 'Option 1' },
{ value: '2', label: 'Option 2' }
]
}
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen
},
selectOption(option) {
this.selectedOption = option.label
this.isOpen = false
}
}
}
</script>
<style scoped>
.dropdown {
position: relative;
display: inline-block;
}
.dropdown ul {
position: absolute;
list-style: none;
padding: 0;
margin: 0;
border: 1px solid #ccc;
}
.dropdown li {
padding: 8px 12px;
cursor: pointer;
}
.dropdown li:hover {
background-color: #f5f5f5;
}
</style>
支持v-model的双向绑定
通过model选项和$emit实现与父组件的双向数据绑定。
export default {
model: {
prop: 'value',
event: 'change'
},
props: {
value: String,
options: {
type: Array,
required: true
}
},
methods: {
selectOption(option) {
this.$emit('change', option.value)
this.isOpen = false
}
}
}
键盘导航支持
增加键盘事件处理提升可访问性。
export default {
mounted() {
document.addEventListener('keydown', this.handleKeyDown)
},
beforeDestroy() {
document.removeEventListener('keydown', this.handleKeyDown)
},
methods: {
handleKeyDown(e) {
if (!this.isOpen) return
if (e.key === 'Escape') this.isOpen = false
if (e.key === 'ArrowDown') this.highlightNext()
if (e.key === 'ArrowUp') this.highlightPrev()
if (e.key === 'Enter' && this.highlightedIndex !== null) {
this.selectOption(this.options[this.highlightedIndex])
}
},
highlightNext() {
// 实现高亮下一个选项的逻辑
}
}
}
异步加载选项
结合Promise或async/await实现异步数据加载。
export default {
data() {
return {
isLoading: false,
asyncOptions: []
}
},
methods: {
async loadOptions() {
this.isLoading = true
try {
const res = await fetch('/api/options')
this.asyncOptions = await res.json()
} finally {
this.isLoading = false
}
}
},
created() {
this.loadOptions()
}
}
多选下拉组件
扩展基础组件实现多选功能。
export default {
props: {
multiple: Boolean
},
data() {
return {
selectedValues: []
}
},
methods: {
selectOption(option) {
if (this.multiple) {
const index = this.selectedValues.indexOf(option.value)
if (index > -1) {
this.selectedValues.splice(index, 1)
} else {
this.selectedValues.push(option.value)
}
} else {
this.selectedValue = option.value
}
}
}
}
虚拟滚动优化
对于大量选项使用虚拟滚动提升性能。
<template>
<div class="dropdown-list" @scroll="handleScroll">
<div class="scroll-content" :style="{ height: totalHeight + 'px' }">
<div
v-for="option in visibleOptions"
:key="option.value"
:style="{ transform: `translateY(${option.offset}px)` }"
>
{{ option.label }}
</div>
</div>
</div>
</template>






