<template>
<div class="multi-select-dropdown">
<input type="text" v-model="searchText" @input="filterOptions" placeholder="搜索..." />
<select v-model="selected" @change="handleChange">
<option v-for="option in filteredOptions" :key="option.value" :value="option.value">
{{ option.label }}
</option>
</select>
<div v-if="showSubOptions" class="sub-options">
<!-- 子级下拉框 -->
<select v-model="selectedSubOption">
<option v-for="subOption in subOptions" :key="subOption.value" :value="subOption.value">
{{ subOption.label }}
</option>
</select>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue';
// 定义 props
const props = defineProps<{
options: Array<{ value: string; label: string; children?: Array<{ value: string; label: string }> }>;
}>();
// 定义 emits
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void;
(e: 'change', value: string): void;
}>();
// 数据
const searchText = ref('');
const selected = ref('');
const showSubOptions = ref(false);
const selectedSubOption = ref('');
// 计算属性
const filteredOptions = computed(() => {
return props.options.filter(option => option.label.includes(searchText.value));
});
// 方法
const handleChange = () => {
const selectedOption = props.options.find(option => option.value === selected.value);
if (selectedOption && selectedOption.children) {
showSubOptions.value = true;
} else {
showSubOptions.value = false;
}
emit('change', selected.value);
};
const filterOptions = () => {
// 根据搜索文本过滤选项
};
// 监听 selected 的变化,更新父组件
watch(selected, (newValue) => {
emit('update:modelValue', newValue);
});
</script>
<style scoped>
.multi-select-dropdown {
/* 样式 */
}
.sub-options {
/* 子级下拉框样式 */
}
</style>
在这个组件中,我们使用了 defineProps
来定义组件的属性,defineEmits
来定义组件可以触发的事件。组件内部使用了 ref
和 computed
来管理数据和计算属性,以及 watch
来监听数据变化并更新父组件。
父组件可以通过 v-model
或事件监听来与这个子组件进行交互。例如:
<template>
<div>
<multi-select-dropdown :options="options" v-model="selectedValue" @change="handleChange" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import MultiSelectDropdown from './MultiSelectDropdown.vue';
const options = [
{ value: '1', label: '选项1', children: [{ value: '1-1', label: '子选项1-1' }] },
{ value: '2', label: '选项2', children: [{ value: '2-1', label: '子选项2-1' }] },
// 更多选项...
];
const selectedValue = ref('');
const handleChange = (value: string) => {
console.log('Selected value changed to:', value);
};
</script>