From da27ad744a0e70b356bea41ccd3ddcfbac458b3f Mon Sep 17 00:00:00 2001 From: K <1175047471@qq.com> Date: Tue, 16 Jul 2024 09:53:10 +0800 Subject: [PATCH] fix(ApiSelect): update code and fix validator error --- .../Form/src/components/ApiSelect.vue | 38 +++++++++---------- .../Form/src/components/FormItem.vue | 11 ++++-- src/components/Form/src/helper.ts | 1 + 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/components/Form/src/components/ApiSelect.vue b/src/components/Form/src/components/ApiSelect.vue index 1c2e8054..43427e63 100644 --- a/src/components/Form/src/components/ApiSelect.vue +++ b/src/components/Form/src/components/ApiSelect.vue @@ -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([]) + +const optionsRef = ref([]) + const loading = ref(false) // 首次是否加载过了 const isFirstLoaded = ref(false) const emitData = ref([]) - 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 } diff --git a/src/components/Form/src/components/FormItem.vue b/src/components/Form/src/components/FormItem.vue index 34e7db8b..045d0550 100644 --- a/src/components/Form/src/components/FormItem.vue +++ b/src/components/Form/src/components/FormItem.vue @@ -197,7 +197,10 @@ export default defineComponent({ */ if (getRequired) { if (!rules || rules.length === 0) { - rules = [{ required: getRequired, validator }] + const trigger = NO_AUTO_LINK_COMPONENTS.includes(component || 'Input') + ? 'blur' + : 'change' + rules = [{ required: getRequired, validator, trigger }] } else { const requiredIndex: number = rules.findIndex(rule => Reflect.has(rule, 'required')) @@ -265,12 +268,12 @@ export default defineComponent({ const on = { [eventKey]: (...args: Nullable>[]) => { const [e] = args - if (propsData[eventKey]) - propsData[eventKey](...args) - const target = e ? e.target : null const value = target ? (isCheck ? target.checked : target.value) : e props.setFormModel(field, value, props.schema) + + if (propsData[eventKey]) + propsData[eventKey](...args) }, } const Comp = componentMap.get(component) as ReturnType diff --git a/src/components/Form/src/helper.ts b/src/components/Form/src/helper.ts index cbd4bfec..121980a8 100644 --- a/src/components/Form/src/helper.ts +++ b/src/components/Form/src/helper.ts @@ -85,4 +85,5 @@ export const NO_AUTO_LINK_COMPONENTS: ComponentType[] = [ 'AutoComplete', 'RadioButtonGroup', 'ImageUpload', + 'ApiSelect', ]