diff --git a/src/components/Form/src/Form.vue b/src/components/Form/src/Form.vue index 04c0adf..547f699 100644 --- a/src/components/Form/src/Form.vue +++ b/src/components/Form/src/Form.vue @@ -183,27 +183,7 @@ export default defineComponent({ const renderFormItem = (item: FormSchema) => { // 单独给只有options属性的组件做判断 // const notRenderOptions = ['SelectV2', 'Cascader', 'Transfer'] - const componentSlots = (item?.componentProps as any)?.slots || {} - const slotsMap: Recordable = { - ...setItemComponentSlots(componentSlots) - } - // 如果是select组件,并且没有自定义模板,自动渲染options - if (item.component === ComponentNameEnum.SELECT) { - slotsMap.default = !componentSlots.default - ? () => renderSelectOptions(item) - : () => { - return componentSlots.default( - unref((item?.componentProps as SelectComponentProps)?.options) - ) - } - } - // 虚拟列表 - if (item.component === ComponentNameEnum.SELECT_V2 && componentSlots.default) { - slotsMap.default = ({ item }: any) => { - return componentSlots.default(item) - } - } // if ( // item?.component !== 'SelectV2' && // item?.component !== 'Cascader' && @@ -268,19 +248,56 @@ export default defineComponent({ label={v[valueAlias]} disabled={v[disabledAlias]} > - {v[labelAlias]} + {() => + componentProps?.slots?.default + ? componentProps?.slots?.default({ option: v }) + : v[labelAlias] + } ) }) } } + const componentSlots = (item?.componentProps as any)?.slots || {} + const slotsMap: Recordable = { + ...setItemComponentSlots(componentSlots) + } + // 如果是select组件,并且没有自定义模板,自动渲染options + if (item.component === ComponentNameEnum.SELECT) { + slotsMap.default = !componentSlots.default + ? () => renderSelectOptions(item) + : () => { + return componentSlots.default( + unref((item?.componentProps as SelectComponentProps)?.options) + ) + } + } + + // 虚拟列表 + if (item.component === ComponentNameEnum.SELECT_V2 && componentSlots.default) { + slotsMap.default = ({ item }) => { + return componentSlots.default(item) + } + } + + // 单选框组 + if (item.component === ComponentNameEnum.RADIO_GROUP) { + slotsMap.default = !componentSlots.default + ? () => renderRadioOptions(item) + : () => { + return componentSlots.default( + unref((item?.componentProps as RadioComponentProps)?.options) + ) + } + } + return ( {{ ...slotsMap }} diff --git a/src/components/Form/src/componentMap.ts b/src/components/Form/src/componentMap.ts index f5d7f17..afd3d12 100644 --- a/src/components/Form/src/componentMap.ts +++ b/src/components/Form/src/componentMap.ts @@ -25,7 +25,7 @@ import { ComponentName } from '@/types/components' const componentMap: Recordable = { Radio: ElRadio, - // RadioGroup: ElRadioGroup, + RadioGroup: ElRadioGroup, Checkbox: ElCheckboxGroup, CheckboxButton: ElCheckboxGroup, Input: ElInput, diff --git a/src/components/Form/src/components/useRenderRadio.tsx b/src/components/Form/src/components/useRenderRadio.tsx index 55fac63..0d2a098 100644 --- a/src/components/Form/src/components/useRenderRadio.tsx +++ b/src/components/Form/src/components/useRenderRadio.tsx @@ -1,23 +1,26 @@ import { FormSchema } from '@/types/form' import { ElRadio, ElRadioButton } from 'element-plus' import { defineComponent } from 'vue' -import { ComponentNameEnum } from '@/types/components.d' +import { ComponentNameEnum, RadioGroupComponentProps } from '@/types/components.d' export const useRenderRadio = () => { - const renderRadioOptions = ( - item: FormSchema, - type?: ComponentNameEnum.RADIO | ComponentNameEnum.RADIO_BUTTON = ComponentNameEnum.RADIO - ) => { + const renderRadioOptions = (item: FormSchema) => { // 如果有别名,就取别名 - const labelAlias = item?.componentProps?.optionsAlias?.labelField - const valueAlias = item?.componentProps?.optionsAlias?.valueField - const Com = (item.component === 'Radio' ? ElRadio : ElRadioButton) as ReturnType< - typeof defineComponent - > - return item?.componentProps?.options?.map((option) => { + const componentProps = item.componentProps as RadioGroupComponentProps + const valueAlias = componentProps?.props?.value || 'value' + const labelAlias = componentProps?.props?.label || 'label' + const disabledAlias = componentProps?.props?.disabled || 'disabled' + const Com = ( + item.component === ComponentNameEnum.RADIO_GROUP ? ElRadio : ElRadioButton + ) as ReturnType + return componentProps?.options?.map((option) => { const { value, ...other } = option return ( - + {option[labelAlias || 'label']} ) diff --git a/src/locales/en.ts b/src/locales/en.ts index 4646233..575e810 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -241,6 +241,7 @@ export default { transfer: 'Transfer', render: 'Render', radio: 'Radio', + radioGroup: 'Radio Group', button: 'Button', checkbox: 'Checkbox', slider: 'Slider', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 4a162c3..c6cd808 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -241,6 +241,7 @@ export default { transfer: '穿梭框', render: '渲染器', radio: '单选框', + radioGroup: '单选框组', button: '按钮', checkbox: '多选框', slider: '滑块', diff --git a/src/types/components.d.ts b/src/types/components.d.ts index 5471e40..28a05a9 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -11,6 +11,7 @@ import { ElementPlusSize, ElementPlusInfoType } from './elementPlus.d' export enum ComponentNameEnum { RADIO = 'Radio', + RADIO_GROUP = 'RadioGroup', RADIO_BUTTON = 'RadioButton', CHECKBOX = 'Checkbox', CHECKBOX_BUTTON = 'CheckboxButton', @@ -453,6 +454,35 @@ export interface RadioComponentProps { slots?: { default?: (...args: any[]) => JSX.Element | null } + style?: CSSProperties +} + +export interface RadioGroupComponentProps { + value?: string | number | boolean + size?: ElementPlusSize + disabled?: boolean + textColor?: string + fill?: string + validateEvent?: boolean + label?: string + name?: string + id?: string + options?: RadioOption[] + /** + * 数据源的字段别名 + */ + props: { + label?: string + value?: string + disabled?: string + } + on?: { + change?: (value: string | number | boolean) => void + } + slots?: { + default?: (...args: any[]) => JSX.Element | null + } + style?: CSSProperties } export interface ColProps { diff --git a/src/types/form.d.ts b/src/types/form.d.ts index 899a921..6cec366 100644 --- a/src/types/form.d.ts +++ b/src/types/form.d.ts @@ -13,7 +13,8 @@ import { RateComponentProps, ColorPickerComponentProps, TransferComponentProps, - RadioComponentProps + RadioComponentProps, + RadioGroupComponentProps } from '@/types/components' import { FormValueType, FormValueType } from '@/types/form' import type { AxiosPromise } from 'axios' @@ -36,31 +37,6 @@ export type FormItemProps = { style?: CSSProperties } -// 定义联合类型和条件类型 -type ComponentPropsForComponent = T extends 'Input' - ? InputComponentProps - : T extends 'Autocomplete' - ? AutocompleteComponentProps - : T extends 'InputNumber' - ? InputNumberComponentProps - : T extends 'Select' - ? SelectComponentProps - : T extends 'SelectV2' - ? SelectV2ComponentProps - : T extends 'Cascader' - ? CascaderComponentProps - : T extends 'Switch' - ? SwitchComponentProps - : T extends 'Rate' - ? RateComponentProps - : T extends 'ColorPicker' - ? ColorPickerComponentProps - : T extends 'Transfer' - ? TransferComponentProps - : T extends 'Radio' - ? RadioComponentProps - : any - export interface FormSchema { /** * 唯一标识 @@ -97,6 +73,7 @@ export interface FormSchema { | ColorPickerComponentProps | TransferComponentProps | RadioComponentProps + | RadioGroupComponentProps /** * formItem组件属性,具体可以查看element-plus文档 diff --git a/src/views/Components/Form/DefaultForm.vue b/src/views/Components/Form/DefaultForm.vue index 7eb02ce..aef5790 100644 --- a/src/views/Components/Form/DefaultForm.vue +++ b/src/views/Components/Form/DefaultForm.vue @@ -6,9 +6,14 @@ import { useIcon } from '@/hooks/web/useIcon' import { ContentWrap } from '@/components/ContentWrap' import { useAppStore } from '@/store/modules/app' import { FormSchema } from '@/types/form' -import { ComponentOptions, SelectOption, SelectComponentProps } from '@/types/components' +import { + ComponentOptions, + SelectOption, + SelectComponentProps, + RadioOption +} from '@/types/components' import { useForm } from '@/hooks/web/useForm' -import { ElOption, ElOptionGroup, ElButton } from 'element-plus' +import { ElOption, ElOptionGroup, ElButton, ElRadio } from 'element-plus' const appStore = useAppStore() @@ -949,6 +954,81 @@ const schema = reactive([ } ] } + }, + { + field: 'field39-1', + label: t('formDemo.slot'), + component: 'Radio', + componentProps: { + options: [ + { + // disabled: true, + label: 'option-1', + value: '1' + }, + { + label: 'option-2', + value: '2' + } + ], + slots: { + default: ({ option }) => { + return ( + <> + {option.label} + ({option.value}) + + ) + } + } + } + }, + { + field: 'field39-2', + label: t('formDemo.radioGroup'), + component: 'RadioGroup', + componentProps: { + options: [ + { + // disabled: true, + label: 'option-1', + value: '1' + }, + { + label: 'option-2', + value: '2' + } + ] + } + }, + { + field: 'field39-3', + label: `${t('formDemo.radioGroup')}${t('formDemo.slot')}`, + component: 'RadioGroup', + componentProps: { + options: [ + { + // disabled: true, + label: 'option-1', + value: '1' + }, + { + label: 'option-2', + value: '2' + } + ], + slots: { + default: (options: RadioOption[]) => { + return options?.map((v) => { + return ( + + {v.label}({v.value}) + + ) + }) + } + } + } } // { // field: 'field40',