1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <template>
- <el-select
- v-model="selected"
- :placeholder="placeholder"
- :clearable="clearable"
- :disabled="disabled"
- filterable
- default-first-option
- v-bind="attrs"
- @change="onChange"
- >
- <el-option
- v-for="item in optionList"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
- </template>
- <script setup lang="ts">
- import { ref, useAttrs, watch } from 'vue';
- import { examQuery } from '@/api/base';
- defineOptions({
- name: 'SelectExam',
- });
- type ValueType = number | Array<number> | null;
- const props = withDefaults(
- defineProps<{
- modelValue: ValueType;
- clearable?: boolean;
- disabled?: boolean;
- placeholder?: string;
- multiple?: boolean;
- }>(),
- {
- clearable: true,
- disabled: false,
- placeholder: '请选择考试',
- multiple: false,
- }
- );
- const emit = defineEmits(['update:modelValue', 'change']);
- const attrs = useAttrs();
- interface OptionListItem {
- value: number;
- label: string;
- }
- const selected = ref<number | Array<number> | undefined>();
- const optionList = ref<OptionListItem[]>([]);
- const search = async () => {
- const res = await examQuery();
- optionList.value = res.map((item) => {
- return { ...item, value: item.id, label: item.name };
- });
- };
- search(); // Initial load
- const onChange = () => {
- const selectedData = props.multiple
- ? optionList.value.filter(
- (item) =>
- selected.value && (selected.value as number[]).includes(item.value)
- )
- : optionList.value.filter((item) => selected.value === item.value);
- emit('update:modelValue', selected.value || null);
- emit('change', props.multiple ? selectedData : selectedData[0]);
- };
- watch(
- () => props.modelValue,
- (val) => {
- selected.value = val || undefined;
- },
- {
- immediate: true,
- }
- );
- </script>
|