|
@@ -0,0 +1,87 @@
|
|
|
|
+<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 { subjectQuery } from '@/api/base';
|
|
|
|
+ import { useAppStore } from '@/store';
|
|
|
|
+
|
|
|
|
+ const appStore = useAppStore();
|
|
|
|
+
|
|
|
|
+ defineOptions({
|
|
|
|
+ name: 'SelectSubject',
|
|
|
|
+ });
|
|
|
|
+ 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 () => {
|
|
|
|
+ if (!appStore.curExam?.id) return;
|
|
|
|
+ const res = await subjectQuery(appStore.curExam?.id);
|
|
|
|
+ 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>
|