|
|
|
@ -3,19 +3,14 @@ import type { PropType } from 'vue'
|
|
|
|
|
import { computed, ref, unref, watch } from 'vue' |
|
|
|
|
import { Select } from 'ant-design-vue' |
|
|
|
|
import type { SelectValue } from 'ant-design-vue/es/select' |
|
|
|
|
import { get, omit } from 'lodash-es' |
|
|
|
|
import { get, isEqual, omit } from 'lodash-es' |
|
|
|
|
import { LoadingOutlined } from '@ant-design/icons-vue' |
|
|
|
|
import { isFunction } from '@/utils/is' |
|
|
|
|
import { useRuleFormItem } from '@/hooks/component/useFormItem' |
|
|
|
|
import { useI18n } from '@/hooks/web/useI18n' |
|
|
|
|
import { propTypes } from '@/utils/propTypes' |
|
|
|
|
|
|
|
|
|
interface OptionsItem { |
|
|
|
|
label?: string |
|
|
|
|
value?: string |
|
|
|
|
disabled?: boolean |
|
|
|
|
[key: string]: any |
|
|
|
|
} |
|
|
|
|
interface OptionsItem { label?: string, value?: string, disabled?: boolean, [name: string]: any } |
|
|
|
|
|
|
|
|
|
defineOptions({ name: 'ApiSelect', inheritAttrs: false }) |
|
|
|
|
|
|
|
|
@ -39,13 +34,15 @@ const props = defineProps({
|
|
|
|
|
default: [], |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
const emit = defineEmits(['options-change', 'change', 'update:value']) |
|
|
|
|
const options = ref<OptionsItem[]>([]) |
|
|
|
|
|
|
|
|
|
const optionsRef = ref<OptionsItem[]>([]) |
|
|
|
|
|
|
|
|
|
const loading = ref(false) |
|
|
|
|
// 首次是否加载过了 |
|
|
|
|
const isFirstLoaded = ref(false) |
|
|
|
|
const emitData = ref<OptionsItem[]>([]) |
|
|
|
|
|
|
|
|
|
const { t } = useI18n() |
|
|
|
|
|
|
|
|
|
// Embedded in the form, just use the hook binding to perform form verification |
|
|
|
@ -54,7 +51,7 @@ const [state] = useRuleFormItem(props, 'value', 'change', emitData)
|
|
|
|
|
const getOptions = computed(() => { |
|
|
|
|
const { labelField, valueField, numberToString } = props |
|
|
|
|
|
|
|
|
|
const data = unref(options).reduce((prev, next: any) => { |
|
|
|
|
const data = unref(optionsRef).reduce((prev, next: any) => { |
|
|
|
|
if (next) { |
|
|
|
|
const value = get(next, valueField) |
|
|
|
|
prev.push({ |
|
|
|
@ -77,8 +74,10 @@ watch(
|
|
|
|
|
|
|
|
|
|
watch( |
|
|
|
|
() => props.params, |
|
|
|
|
() => { |
|
|
|
|
!unref(isFirstLoaded) && fetch() |
|
|
|
|
(value, oldValue) => { |
|
|
|
|
if (isEqual(value, oldValue)) |
|
|
|
|
return |
|
|
|
|
fetch() |
|
|
|
|
}, |
|
|
|
|
{ deep: true, immediate: props.immediate }, |
|
|
|
|
) |
|
|
|
@ -87,33 +86,33 @@ async function fetch() {
|
|
|
|
|
const api = props.api |
|
|
|
|
if (!api || !isFunction(api) || loading.value) |
|
|
|
|
return |
|
|
|
|
options.value = [] |
|
|
|
|
optionsRef.value = [] |
|
|
|
|
try { |
|
|
|
|
loading.value = true |
|
|
|
|
const res = await api(props.params) |
|
|
|
|
isFirstLoaded.value = true |
|
|
|
|
if (Array.isArray(res)) { |
|
|
|
|
options.value = res |
|
|
|
|
optionsRef.value = res |
|
|
|
|
emitChange() |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
if (props.resultField) |
|
|
|
|
options.value = get(res, props.resultField) || [] |
|
|
|
|
optionsRef.value = get(res, props.resultField) || [] |
|
|
|
|
|
|
|
|
|
emitChange() |
|
|
|
|
} |
|
|
|
|
catch (error) { |
|
|
|
|
console.warn(error) |
|
|
|
|
// reset status |
|
|
|
|
isFirstLoaded.value = false |
|
|
|
|
} |
|
|
|
|
finally { |
|
|
|
|
loading.value = false |
|
|
|
|
// reset status |
|
|
|
|
isFirstLoaded.value = false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function handleFetch(open: boolean) { |
|
|
|
|
if (open) { |
|
|
|
|
async function handleFetch(visible: boolean) { |
|
|
|
|
if (visible) { |
|
|
|
|
if (props.alwaysLoad) |
|
|
|
|
await fetch() |
|
|
|
|
else if (!props.immediate && !unref(isFirstLoaded)) |
|
|
|
@ -126,7 +125,6 @@ function emitChange() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function handleChange(_, ...args) { |
|
|
|
|
emit('change', args[0] ? args[0].value : undefined) |
|
|
|
|
emitData.value = args |
|
|
|
|
} |
|
|
|
|
</script> |
|
|
|
|