vue实现selected组件
实现基础下拉选择组件
使用Vue的v-model和v-for指令创建基础下拉选择框。通过select元素绑定值,option元素动态渲染选项列表。
<template>
<select v-model="selectedValue">
<option
v-for="option in options"
:key="option.value"
:value="option.value"
>
{{ option.label }}
</option>
</select>
</template>
<script>
export default {
data() {
return {
selectedValue: '',
options: [
{ value: '1', label: '选项1' },
{ value: '2', label: '选项2' }
]
}
}
}
</script>
添加自定义样式和功能
使用div模拟下拉框实现更灵活的样式控制。通过v-show控制下拉列表显示状态,添加点击事件处理展开/收起逻辑。
<template>
<div class="custom-select">
<div
class="selected-option"
@click="toggleDropdown"
>
{{ selectedLabel }}
<span class="arrow">▼</span>
</div>
<div
class="options-list"
v-show="isOpen"
>
<div
v-for="option in options"
:key="option.value"
@click="selectOption(option)"
>
{{ option.label }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isOpen: false,
selectedValue: '',
selectedLabel: '请选择',
options: [
{ value: '1', label: '选项1' },
{ value: '2', label: '选项2' }
]
}
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen
},
selectOption(option) {
this.selectedValue = option.value
this.selectedLabel = option.label
this.isOpen = false
}
}
}
</script>
<style>
.custom-select {
position: relative;
width: 200px;
}
.selected-option {
padding: 8px;
border: 1px solid #ccc;
cursor: pointer;
}
.options-list {
position: absolute;
width: 100%;
border: 1px solid #ccc;
max-height: 200px;
overflow-y: auto;
}
.options-list div {
padding: 8px;
cursor: pointer;
}
.options-list div:hover {
background-color: #f0f0f0;
}
.arrow {
float: right;
}
</style>
封装为可复用组件
将选择器封装为独立组件,通过props接收选项列表,通过emit事件传递选择结果。
<!-- Select.vue -->
<template>
<div class="custom-select">
<div class="selected-option" @click="toggleDropdown">
{{ selectedLabel || placeholder }}
<span class="arrow">▼</span>
</div>
<div class="options-list" v-show="isOpen">
<div
v-for="option in options"
:key="option.value"
@click="selectOption(option)"
>
{{ option.label }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Array,
required: true
},
value: {
type: [String, Number],
default: ''
},
placeholder: {
type: String,
default: '请选择'
}
},
data() {
return {
isOpen: false,
selectedValue: this.value,
selectedLabel: ''
}
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen
},
selectOption(option) {
this.selectedValue = option.value
this.selectedLabel = option.label
this.$emit('input', option.value)
this.$emit('change', option)
this.isOpen = false
}
},
watch: {
value(newVal) {
this.selectedValue = newVal
const selectedOption = this.options.find(opt => opt.value === newVal)
this.selectedLabel = selectedOption ? selectedOption.label : ''
}
}
}
</style>
在父组件中使用
通过v-model绑定选择器值,监听change事件获取完整选项对象。
<template>
<div>
<Select
v-model="selectedValue"
:options="options"
placeholder="选择城市"
@change="handleChange"
/>
<p>当前选择的值: {{ selectedValue }}</p>
</div>
</template>
<script>
import Select from './Select.vue'
export default {
components: { Select },
data() {
return {
selectedValue: '',
options: [
{ value: 'bj', label: '北京' },
{ value: 'sh', label: '上海' }
]
}
},
methods: {
handleChange(option) {
console.log('选择的完整对象:', option)
}
}
}
</script>
添加搜索过滤功能
扩展选择器组件,增加搜索框过滤选项功能。
<template>
<div class="custom-select">
<div class="selected-option" @click="toggleDropdown">
{{ selectedLabel || placeholder }}
<span class="arrow">▼</span>
</div>
<div class="options-list" v-show="isOpen">
<input
v-model="searchText"
class="search-input"
placeholder="搜索..."
@click.stop
/>
<div
v-for="option in filteredOptions"
:key="option.value"
@click="selectOption(option)"
>
{{ option.label }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: Array,
value: [String, Number],
placeholder: String
},
data() {
return {
isOpen: false,
selectedValue: this.value,
selectedLabel: '',
searchText: ''
}
},
computed: {
filteredOptions() {
return this.options.filter(option =>
option.label.toLowerCase().includes(this.searchText.toLowerCase())
)
}
},
methods: {
toggleDropdown() {
this.isOpen = !this.isOpen
if (this.isOpen) {
this.searchText = ''
}
},
selectOption(option) {
this.selectedValue = option.value
this.selectedLabel = option.label
this.$emit('input', option.value)
this.$emit('change', option)
this.isOpen = false
}
},
watch: {
value(newVal) {
this.selectedValue = newVal
const selectedOption = this.options.find(opt => opt.value === newVal)
this.selectedLabel = selectedOption ? selectedOption.label : ''
}
}
}
</script>
<style>
.search-input {
width: 100%;
padding: 8px;
box-sizing: border-box;
}
</style>






