From d6749f95c526c0e71ec946bd3bb777bc42b2c34a Mon Sep 17 00:00:00 2001 From: Ben Lin <maobin001@msn.com> Date: 星期日, 20 十月 2024 17:59:31 +0800 Subject: [PATCH] 工艺绑定优化 --- src/components/Form/src/components/ApiRadioGroup.vue | 227 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 116 insertions(+), 111 deletions(-) diff --git a/src/components/Form/src/components/ApiRadioGroup.vue b/src/components/Form/src/components/ApiRadioGroup.vue index 8285cdf..f90daa2 100644 --- a/src/components/Form/src/components/ApiRadioGroup.vue +++ b/src/components/Form/src/components/ApiRadioGroup.vue @@ -2,135 +2,140 @@ * @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component --> <template> - <RadioGroup v-bind="attrs" v-model:value="state" button-style="solid"> + <Radio.Group v-bind="attrs" v-model:value="state" button-style="solid"> <template v-for="item in getOptions" :key="`${item.value}`"> - <RadioButton + <Radio.Button v-if="props.isBtn" :value="item.value" :disabled="item.disabled" @click="handleClick(item)" > {{ item.label }} - </RadioButton> + </Radio.Button> <Radio v-else :value="item.value" :disabled="item.disabled" @click="handleClick(item)"> {{ item.label }} </Radio> </template> - </RadioGroup> + </Radio.Group> </template> -<script lang="ts"> - import { defineComponent, type PropType, ref, watchEffect, computed, unref, watch } from 'vue'; +<script lang="ts" setup> + import { type PropType, ref, computed, unref, watch } from 'vue'; import { Radio } from 'ant-design-vue'; - import { isFunction } from '/@/utils/is'; - import { useRuleFormItem } from '/@/hooks/component/useFormItem'; + import { isFunction } from '@/utils/is'; + import { useRuleFormItem } from '@/hooks/component/useFormItem'; import { useAttrs } from '@vben/hooks'; - import { propTypes } from '/@/utils/propTypes'; - import { get, omit } from 'lodash-es'; - import { useI18n } from '/@/hooks/web/useI18n'; + import { propTypes } from '@/utils/propTypes'; + import { get, omit, isEqual } from 'lodash-es'; - type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean }; + type OptionsItem = { + label?: string; + value?: string | number | boolean; + disabled?: boolean; + [key: string]: any; + }; - export default defineComponent({ - name: 'ApiRadioGroup', - components: { - RadioGroup: Radio.Group, - RadioButton: Radio.Button, - Radio, + defineOptions({ name: 'ApiRadioGroup' }); + + const props = defineProps({ + api: { + type: Function as PropType<(arg?: any) => Promise<OptionsItem[] | Recordable<any>>>, + default: null, }, - props: { - api: { - type: Function as PropType<(arg?: any | string) => Promise<OptionsItem[]>>, - default: null, - }, - params: { - type: [Object, String] as PropType<any | string>, - default: () => ({}), - }, - value: { - type: [String, Number, Boolean] as PropType<string | number | boolean>, - }, - isBtn: { - type: [Boolean] as PropType<boolean>, - default: false, - }, - numberToString: propTypes.bool, - resultField: propTypes.string.def(''), - labelField: propTypes.string.def('label'), - valueField: propTypes.string.def('value'), - immediate: propTypes.bool.def(true), + params: { + type: [Object, String] as PropType<any | string>, + default: () => ({}), }, - emits: ['options-change', 'change'], - setup(props, { emit }) { - const options = ref<OptionsItem[]>([]); - const loading = ref(false); - const isFirstLoad = ref(true); - const emitData = ref<any[]>([]); - const attrs = useAttrs(); - const { t } = useI18n(); - // Embedded in the form, just use the hook binding to perform form verification - const [state] = useRuleFormItem(props, 'value', 'change', emitData); - - // Processing options value - const getOptions = computed(() => { - const { labelField, valueField, numberToString } = props; - - return unref(options).reduce((prev, next: any) => { - if (next) { - const value = next[valueField]; - prev.push({ - label: next[labelField], - value: numberToString ? `${value}` : value, - ...omit(next, [labelField, valueField]), - }); - } - return prev; - }, [] as OptionsItem[]); - }); - - watchEffect(() => { - props.immediate && fetch(); - }); - - watch( - () => props.params, - () => { - !unref(isFirstLoad) && fetch(); - }, - { deep: true }, - ); - - async function fetch() { - const api = props.api; - if (!api || !isFunction(api)) return; - options.value = []; - try { - loading.value = true; - const res = await api(props.params); - if (Array.isArray(res)) { - options.value = res; - emitChange(); - return; - } - if (props.resultField) { - options.value = get(res, props.resultField) || []; - } - emitChange(); - } catch (error) { - console.warn(error); - } finally { - loading.value = false; - } - } - - function emitChange() { - emit('options-change', unref(getOptions)); - } - - function handleClick(...args) { - emitData.value = args; - } - - return { state, getOptions, attrs, loading, t, handleClick, props }; + value: { + type: [String, Number, Boolean] as PropType<string | number | boolean>, + }, + isBtn: { + type: [Boolean] as PropType<boolean>, + default: false, + }, + numberToString: propTypes.bool, + resultField: propTypes.string.def(''), + labelField: propTypes.string.def('label'), + valueField: propTypes.string.def('value'), + immediate: propTypes.bool.def(true), + beforeFetch: { + type: Function as PropType<Fn>, + default: null, + }, + afterFetch: { + type: Function as PropType<Fn>, + default: null, }, }); + + const emit = defineEmits(['options-change', 'change', 'update:value']); + + const options = ref<OptionsItem[]>([]); + const loading = ref(false); + const emitData = ref<any[]>([]); + const attrs = useAttrs(); + // Embedded in the form, just use the hook binding to perform form verification + const [state] = useRuleFormItem(props, 'value', 'change', emitData); + + // Processing options value + const getOptions = computed(() => { + const { labelField, valueField, numberToString } = props; + + return unref(options).reduce((prev, next: any) => { + if (next) { + const value = next[valueField]; + prev.push({ + label: next[labelField], + value: numberToString ? `${value}` : value, + ...omit(next, [labelField, valueField]), + }); + } + return prev; + }, [] as OptionsItem[]); + }); + + watch( + () => props.params, + (value, oldValue) => { + if (isEqual(value, oldValue)) return; + fetch(); + }, + { deep: true, immediate: props.immediate }, + ); + + async function fetch() { + let { api, beforeFetch, afterFetch, params, resultField } = props; + if (!api || !isFunction(api)) return; + options.value = []; + try { + loading.value = true; + if (beforeFetch && isFunction(beforeFetch)) { + params = (await beforeFetch(params)) || params; + } + let res = await api(params); + if (afterFetch && isFunction(afterFetch)) { + res = (await afterFetch(res)) || res; + } + if (Array.isArray(res)) { + options.value = res; + emitChange(); + return; + } + if (resultField) { + options.value = get(res, resultField) || []; + } + emitChange(); + } catch (error) { + console.warn(error); + } finally { + loading.value = false; + } + } + + function emitChange() { + emit('options-change', unref(getOptions)); + } + + function handleClick(...args) { + emitData.value = args; + } </script> -- Gitblit v1.9.3