index.vue 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <template>
  2. <el-select
  3. v-model="selected"
  4. :placeholder="placeholder"
  5. :clearable="clearable"
  6. :disabled="disabled"
  7. filterable
  8. default-first-option
  9. v-bind="attrs"
  10. @change="onChange"
  11. >
  12. <el-option
  13. v-for="item in optionList"
  14. :key="item.value"
  15. :label="item.label"
  16. :value="item.value"
  17. />
  18. </el-select>
  19. </template>
  20. <script setup lang="ts">
  21. import { ref, useAttrs, watch } from 'vue';
  22. import { examQuery } from '@/api/base';
  23. defineOptions({
  24. name: 'SelectExam',
  25. });
  26. type ValueType = number | Array<number> | null;
  27. const props = withDefaults(
  28. defineProps<{
  29. modelValue: ValueType;
  30. clearable?: boolean;
  31. disabled?: boolean;
  32. placeholder?: string;
  33. multiple?: boolean;
  34. }>(),
  35. {
  36. clearable: true,
  37. disabled: false,
  38. placeholder: '请选择考试',
  39. multiple: false,
  40. }
  41. );
  42. const emit = defineEmits(['update:modelValue', 'change']);
  43. const attrs = useAttrs();
  44. interface OptionListItem {
  45. value: number;
  46. label: string;
  47. }
  48. const selected = ref<number | Array<number> | undefined>();
  49. const optionList = ref<OptionListItem[]>([]);
  50. const search = async () => {
  51. const res = await examQuery();
  52. optionList.value = res.map((item) => {
  53. return { ...item, value: item.id, label: item.name };
  54. });
  55. };
  56. search(); // Initial load
  57. const onChange = () => {
  58. const selectedData = props.multiple
  59. ? optionList.value.filter(
  60. (item) =>
  61. selected.value && (selected.value as number[]).includes(item.value)
  62. )
  63. : optionList.value.filter((item) => selected.value === item.value);
  64. emit('update:modelValue', selected.value || null);
  65. emit('change', props.multiple ? selectedData : selectedData[0]);
  66. };
  67. watch(
  68. () => props.modelValue,
  69. (val) => {
  70. selected.value = val || undefined;
  71. },
  72. {
  73. immediate: true,
  74. }
  75. );
  76. </script>