Commit 0c57c6d7f244b5b4e4ee8fef3aad9a7fa327fb0f

Authored by fengtao
1 parent 2161ab68

feat:新增Form 里的远程下拉radio,精简版没有,完整版有

@@ -9,5 +9,7 @@ export { useForm } from './src/hooks/useForm'; @@ -9,5 +9,7 @@ export { useForm } from './src/hooks/useForm';
9 export { default as ApiSelect } from './src/components/ApiSelect.vue'; 9 export { default as ApiSelect } from './src/components/ApiSelect.vue';
10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue'; 10 export { default as RadioButtonGroup } from './src/components/RadioButtonGroup.vue';
11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue'; 11 export { default as ApiTreeSelect } from './src/components/ApiTreeSelect.vue';
  12 +export { default as ApiRadioGroup } from './src/components/ApiRadioGroup.vue';
  13 +
12 14
13 export { BasicForm }; 15 export { BasicForm };
@@ -27,6 +27,7 @@ import { BasicUpload } from '/@/components/Upload'; @@ -27,6 +27,7 @@ import { BasicUpload } from '/@/components/Upload';
27 import { StrengthMeter } from '/@/components/StrengthMeter'; 27 import { StrengthMeter } from '/@/components/StrengthMeter';
28 import { IconPicker } from '/@/components/Icon'; 28 import { IconPicker } from '/@/components/Icon';
29 import { CountdownInput } from '/@/components/CountDown'; 29 import { CountdownInput } from '/@/components/CountDown';
  30 +import ApiRadioGroup from './components/ApiRadioGroup.vue';
30 //自定义组件 31 //自定义组件
31 import JAddInput from './jeecg/components/JAddInput.vue'; 32 import JAddInput from './jeecg/components/JAddInput.vue';
32 33
@@ -39,6 +40,7 @@ componentMap.set('InputSearch', Input.Search); @@ -39,6 +40,7 @@ componentMap.set('InputSearch', Input.Search);
39 componentMap.set('InputTextArea', Input.TextArea); 40 componentMap.set('InputTextArea', Input.TextArea);
40 componentMap.set('InputNumber', InputNumber); 41 componentMap.set('InputNumber', InputNumber);
41 componentMap.set('AutoComplete', AutoComplete); 42 componentMap.set('AutoComplete', AutoComplete);
  43 +componentMap.set('ApiRadioGroup', ApiRadioGroup);
42 44
43 componentMap.set('Select', Select); 45 componentMap.set('Select', Select);
44 componentMap.set('ApiSelect', ApiSelect); 46 componentMap.set('ApiSelect', ApiSelect);
  1 +<!--
  2 + * @Description:It is troublesome to implement radio button group in the form. So it is extracted independently as a separate component
  3 +-->
  4 +<template>
  5 + <RadioGroup v-bind="attrs" v-model:value="state" button-style="solid" @change="handleChange">
  6 + <template v-for="item in getOptions" :key="`${item.value}`">
  7 + <RadioButton v-if="props.isBtn" :value="item.value" :disabled="item.disabled">
  8 + {{ item.label }}
  9 + </RadioButton>
  10 + <Radio v-else :value="item.value" :disabled="item.disabled">
  11 + {{ item.label }}
  12 + </Radio>
  13 + </template>
  14 + </RadioGroup>
  15 +</template>
  16 +<script lang="ts">
  17 + import { defineComponent, PropType, ref, watchEffect, computed, unref, watch } from 'vue';
  18 + import { Radio } from 'ant-design-vue';
  19 + import { isFunction } from '/@/utils/is';
  20 + import { useRuleFormItem } from '/@/hooks/component/useFormItem';
  21 + import { useAttrs } from '/@/hooks/core/useAttrs';
  22 + import { propTypes } from '/@/utils/propTypes';
  23 + import { get, omit } from 'lodash-es';
  24 + import { useI18n } from '/@/hooks/web/useI18n';
  25 + type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
  26 +
  27 + export default defineComponent({
  28 + name: 'ApiRadioGroup',
  29 + components: {
  30 + RadioGroup: Radio.Group,
  31 + RadioButton: Radio.Button,
  32 + Radio,
  33 + },
  34 + props: {
  35 + api: {
  36 + type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>,
  37 + default: null,
  38 + },
  39 + params: {
  40 + type: [Object, String] as PropType<Recordable | string>,
  41 + default: () => ({}),
  42 + },
  43 + value: {
  44 + type: [String, Number, Boolean] as PropType<string | number | boolean>,
  45 + },
  46 + isBtn: {
  47 + type: [Boolean] as PropType<boolean>,
  48 + default: false,
  49 + },
  50 + numberToString: propTypes.bool,
  51 + resultField: propTypes.string.def(''),
  52 + labelField: propTypes.string.def('label'),
  53 + valueField: propTypes.string.def('value'),
  54 + immediate: propTypes.bool.def(true),
  55 + },
  56 + emits: ['options-change', 'change'],
  57 + setup(props, { emit }) {
  58 + const options = ref<OptionsItem[]>([]);
  59 + const loading = ref(false);
  60 + const isFirstLoad = ref(true);
  61 + const emitData = ref<any[]>([]);
  62 + const attrs = useAttrs();
  63 + const { t } = useI18n();
  64 + // Embedded in the form, just use the hook binding to perform form verification
  65 + const [state] = useRuleFormItem(props);
  66 +
  67 + // Processing options value
  68 + const getOptions = computed(() => {
  69 + const { labelField, valueField, numberToString } = props;
  70 +
  71 + return unref(options).reduce((prev, next: Recordable) => {
  72 + if (next) {
  73 + const value = next[valueField];
  74 + prev.push({
  75 + label: next[labelField],
  76 + value: numberToString ? `${value}` : value,
  77 + ...omit(next, [labelField, valueField]),
  78 + });
  79 + }
  80 + return prev;
  81 + }, [] as OptionsItem[]);
  82 + });
  83 +
  84 + watchEffect(() => {
  85 + props.immediate && fetch();
  86 + });
  87 +
  88 + watch(
  89 + () => props.params,
  90 + () => {
  91 + !unref(isFirstLoad) && fetch();
  92 + },
  93 + { deep: true },
  94 + );
  95 +
  96 + async function fetch() {
  97 + const api = props.api;
  98 + if (!api || !isFunction(api)) return;
  99 + options.value = [];
  100 + try {
  101 + loading.value = true;
  102 + const res = await api(props.params);
  103 + if (Array.isArray(res)) {
  104 + options.value = res;
  105 + emitChange();
  106 + return;
  107 + }
  108 + if (props.resultField) {
  109 + options.value = get(res, props.resultField) || [];
  110 + }
  111 + emitChange();
  112 + } catch (error) {
  113 + console.warn(error);
  114 + } finally {
  115 + loading.value = false;
  116 + }
  117 + }
  118 +
  119 + function emitChange() {
  120 + emit('options-change', unref(getOptions));
  121 + }
  122 +
  123 + function handleChange(_, ...args) {
  124 + emitData.value = args;
  125 + }
  126 +
  127 + return { state, getOptions, attrs, loading, t, handleChange, props };
  128 + },
  129 + });
  130 +</script>
@@ -82,6 +82,7 @@ export interface ColEx { @@ -82,6 +82,7 @@ export interface ColEx {
82 82
83 export type ComponentType = 83 export type ComponentType =
84 | 'Input' 84 | 'Input'
  85 + | 'ApiRadioGroup'
85 | 'InputGroup' 86 | 'InputGroup'
86 | 'InputPassword' 87 | 'InputPassword'
87 | 'InputSearch' 88 | 'InputSearch'