wip: Form改造中

This commit is contained in:
kailong321200875 2023-05-24 18:14:36 +08:00
parent 83513d519d
commit 6f1a94809e
8 changed files with 172 additions and 63 deletions

View File

@ -183,27 +183,7 @@ export default defineComponent({
const renderFormItem = (item: FormSchema) => { const renderFormItem = (item: FormSchema) => {
// options // options
// const notRenderOptions = ['SelectV2', 'Cascader', 'Transfer'] // const notRenderOptions = ['SelectV2', 'Cascader', 'Transfer']
const componentSlots = (item?.componentProps as any)?.slots || {}
const slotsMap: Recordable = {
...setItemComponentSlots(componentSlots)
}
// selectoptions
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 ( // if (
// item?.component !== 'SelectV2' && // item?.component !== 'SelectV2' &&
// item?.component !== 'Cascader' && // item?.component !== 'Cascader' &&
@ -268,19 +248,56 @@ export default defineComponent({
label={v[valueAlias]} label={v[valueAlias]}
disabled={v[disabledAlias]} disabled={v[disabledAlias]}
> >
{v[labelAlias]} {() =>
componentProps?.slots?.default
? componentProps?.slots?.default({ option: v })
: v[labelAlias]
}
</Com> </Com>
) )
}) })
} }
} }
const componentSlots = (item?.componentProps as any)?.slots || {}
const slotsMap: Recordable = {
...setItemComponentSlots(componentSlots)
}
// selectoptions
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 ( return (
<Com <Com
vModel={formModel.value[item.field]} vModel={formModel.value[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))} {...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item)} {...setComponentProps(item)}
style={item.componentProps?.style} style={item.componentProps?.style || {}}
> >
{{ ...slotsMap }} {{ ...slotsMap }}
</Com> </Com>

View File

@ -25,7 +25,7 @@ import { ComponentName } from '@/types/components'
const componentMap: Recordable<Component, ComponentName> = { const componentMap: Recordable<Component, ComponentName> = {
Radio: ElRadio, Radio: ElRadio,
// RadioGroup: ElRadioGroup, RadioGroup: ElRadioGroup,
Checkbox: ElCheckboxGroup, Checkbox: ElCheckboxGroup,
CheckboxButton: ElCheckboxGroup, CheckboxButton: ElCheckboxGroup,
Input: ElInput, Input: ElInput,

View File

@ -1,23 +1,26 @@
import { FormSchema } from '@/types/form' import { FormSchema } from '@/types/form'
import { ElRadio, ElRadioButton } from 'element-plus' import { ElRadio, ElRadioButton } from 'element-plus'
import { defineComponent } from 'vue' import { defineComponent } from 'vue'
import { ComponentNameEnum } from '@/types/components.d' import { ComponentNameEnum, RadioGroupComponentProps } from '@/types/components.d'
export const useRenderRadio = () => { export const useRenderRadio = () => {
const renderRadioOptions = ( const renderRadioOptions = (item: FormSchema) => {
item: FormSchema,
type?: ComponentNameEnum.RADIO | ComponentNameEnum.RADIO_BUTTON = ComponentNameEnum.RADIO
) => {
// 如果有别名,就取别名 // 如果有别名,就取别名
const labelAlias = item?.componentProps?.optionsAlias?.labelField const componentProps = item.componentProps as RadioGroupComponentProps
const valueAlias = item?.componentProps?.optionsAlias?.valueField const valueAlias = componentProps?.props?.value || 'value'
const Com = (item.component === 'Radio' ? ElRadio : ElRadioButton) as ReturnType< const labelAlias = componentProps?.props?.label || 'label'
typeof defineComponent const disabledAlias = componentProps?.props?.disabled || 'disabled'
> const Com = (
return item?.componentProps?.options?.map((option) => { item.component === ComponentNameEnum.RADIO_GROUP ? ElRadio : ElRadioButton
) as ReturnType<typeof defineComponent>
return componentProps?.options?.map((option) => {
const { value, ...other } = option const { value, ...other } = option
return ( return (
<Com {...other} label={option[valueAlias || 'value']}> <Com
{...other}
disabled={option[disabledAlias || 'disabled']}
label={option[valueAlias || 'value']}
>
{option[labelAlias || 'label']} {option[labelAlias || 'label']}
</Com> </Com>
) )

View File

@ -241,6 +241,7 @@ export default {
transfer: 'Transfer', transfer: 'Transfer',
render: 'Render', render: 'Render',
radio: 'Radio', radio: 'Radio',
radioGroup: 'Radio Group',
button: 'Button', button: 'Button',
checkbox: 'Checkbox', checkbox: 'Checkbox',
slider: 'Slider', slider: 'Slider',

View File

@ -241,6 +241,7 @@ export default {
transfer: '穿梭框', transfer: '穿梭框',
render: '渲染器', render: '渲染器',
radio: '单选框', radio: '单选框',
radioGroup: '单选框组',
button: '按钮', button: '按钮',
checkbox: '多选框', checkbox: '多选框',
slider: '滑块', slider: '滑块',

View File

@ -11,6 +11,7 @@ import { ElementPlusSize, ElementPlusInfoType } from './elementPlus.d'
export enum ComponentNameEnum { export enum ComponentNameEnum {
RADIO = 'Radio', RADIO = 'Radio',
RADIO_GROUP = 'RadioGroup',
RADIO_BUTTON = 'RadioButton', RADIO_BUTTON = 'RadioButton',
CHECKBOX = 'Checkbox', CHECKBOX = 'Checkbox',
CHECKBOX_BUTTON = 'CheckboxButton', CHECKBOX_BUTTON = 'CheckboxButton',
@ -453,6 +454,35 @@ export interface RadioComponentProps {
slots?: { slots?: {
default?: (...args: any[]) => JSX.Element | null 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 { export interface ColProps {

29
src/types/form.d.ts vendored
View File

@ -13,7 +13,8 @@ import {
RateComponentProps, RateComponentProps,
ColorPickerComponentProps, ColorPickerComponentProps,
TransferComponentProps, TransferComponentProps,
RadioComponentProps RadioComponentProps,
RadioGroupComponentProps
} from '@/types/components' } from '@/types/components'
import { FormValueType, FormValueType } from '@/types/form' import { FormValueType, FormValueType } from '@/types/form'
import type { AxiosPromise } from 'axios' import type { AxiosPromise } from 'axios'
@ -36,31 +37,6 @@ export type FormItemProps = {
style?: CSSProperties style?: CSSProperties
} }
// 定义联合类型和条件类型
type ComponentPropsForComponent<T extends ComponentName> = 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 { export interface FormSchema {
/** /**
* *
@ -97,6 +73,7 @@ export interface FormSchema {
| ColorPickerComponentProps | ColorPickerComponentProps
| TransferComponentProps | TransferComponentProps
| RadioComponentProps | RadioComponentProps
| RadioGroupComponentProps
/** /**
* formItem组件属性element-plus文档 * formItem组件属性element-plus文档

View File

@ -6,9 +6,14 @@ import { useIcon } from '@/hooks/web/useIcon'
import { ContentWrap } from '@/components/ContentWrap' import { ContentWrap } from '@/components/ContentWrap'
import { useAppStore } from '@/store/modules/app' import { useAppStore } from '@/store/modules/app'
import { FormSchema } from '@/types/form' 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 { useForm } from '@/hooks/web/useForm'
import { ElOption, ElOptionGroup, ElButton } from 'element-plus' import { ElOption, ElOptionGroup, ElButton, ElRadio } from 'element-plus'
const appStore = useAppStore() const appStore = useAppStore()
@ -949,6 +954,81 @@ const schema = reactive<FormSchema[]>([
} }
] ]
} }
},
{
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 (
<>
<span>{option.label}</span>
<span> ({option.value}) </span>
</>
)
}
}
}
},
{
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 (
<ElRadio label={v.value}>
{v.label}({v.value})
</ElRadio>
)
})
}
}
}
} }
// { // {
// field: 'field40', // field: 'field40',