Skip to content

Commit

Permalink
feat: Radio改造
Browse files Browse the repository at this point in the history
  • Loading branch information
kailong321200875 committed May 23, 2023
1 parent 64d436b commit 83513d5
Show file tree
Hide file tree
Showing 10 changed files with 274 additions and 161 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"dayjs": "^1.11.7",
"echarts": "^5.4.2",
"echarts-wordcloud": "^2.1.0",
"element-plus": "2.3.5",
"element-plus": "^2.3.5",
"intro.js": "^7.0.1",
"lodash-es": "^4.17.21",
"mitt": "^3.0.0",
Expand Down
106 changes: 70 additions & 36 deletions src/components/Form/src/Form.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ import { set } from 'lodash-es'
import { FormProps } from './types'
import { Icon } from '@/components/Icon'
import { FormSchema, FormSetPropsType } from '@/types/form'
import { ComponentNameEnum, SelectComponentProps, SelectOption } from '@/types/components.d'
import {
ComponentNameEnum,
SelectComponentProps,
SelectOption,
RadioComponentProps
} from '@/types/components.d'
const { renderSelectOptions } = useRenderSelect()
const { renderRadioOptions } = useRenderRadio()
const { renderCheckboxOptions } = useRenderCheckbox()
const { getPrefixCls } = useDesign()
Expand Down Expand Up @@ -181,7 +190,7 @@ export default defineComponent({
// 如果是select组件,并且没有自定义模板,自动渲染options
if (item.component === ComponentNameEnum.SELECT) {
slotsMap.default = !componentSlots.default
? () => renderOptions(item)
? () => renderSelectOptions(item)
: () => {
return componentSlots.default(
unref((item?.componentProps as SelectComponentProps)?.options)
Expand Down Expand Up @@ -231,48 +240,73 @@ export default defineComponent({
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
{{
default: () => {
const Com = componentMap[item.component as string] as ReturnType<
typeof defineComponent
>
const { autoSetPlaceholder } = unref(getProps)
return slots[item.field] ? (
getSlot(slots, item.field, formModel.value)
) : (
<Com
vModel={formModel.value[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item)}
style={item.componentProps?.style}
if (slots[item.field]) {
return getSlot(slots, item.field, formModel.value)
} else {
const Com = componentMap[item.component as string] as ReturnType<
typeof defineComponent
>
{{ ...slotsMap }}
</Com>
)
const { autoSetPlaceholder } = unref(getProps)
// 需要特殊处理的组件
const specialComponents = [ComponentNameEnum.RADIO]
if (specialComponents.findIndex((v) => v === item.component) !== -1) {
switch (item.component) {
case ComponentNameEnum.RADIO:
const componentProps = item.componentProps as RadioComponentProps
const valueAlias = componentProps?.props?.value || 'value'
const labelAlias = componentProps?.props?.label || 'label'
const disabledAlias = componentProps?.props?.disabled || 'disabled'
return componentProps?.options?.map((v) => {
return (
<Com
vModel={formModel.value[item.field]}
{...setComponentProps(item)}
label={v[valueAlias]}
disabled={v[disabledAlias]}
>
{v[labelAlias]}
</Com>
)
})
}
}
return (
<Com
vModel={formModel.value[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item)}
style={item.componentProps?.style}
>
{{ ...slotsMap }}
</Com>
)
}
}
}}
</ElFormItem>
)
}
// 渲染options
const renderOptions = (item: FormSchema) => {
switch (item.component) {
case ComponentNameEnum.SELECT:
const { renderSelectOptions } = useRenderSelect()
return renderSelectOptions(item)
case 'Radio':
case 'RadioButton':
const { renderRadioOptions } = useRenderRadio()
return renderRadioOptions(item)
case 'Checkbox':
case 'CheckboxButton':
const { renderCheckboxOptions } = useRenderCheckbox()
return renderCheckboxOptions(item)
default:
break
}
}
// const renderOptions = (item: FormSchema) => {
// switch (item.component) {
// case ComponentNameEnum.SELECT:
// return renderSelectOptions(item)
// case ComponentNameEnum.RADIO:
// case 'RadioButton':
// return renderRadioOptions(item)
// case 'Checkbox':
// case 'CheckboxButton':
// return renderCheckboxOptions(item)
// default:
// break
// }
// }
// 过滤传入Form组件的属性
const getFormBindValue = () => {
Expand Down
6 changes: 4 additions & 2 deletions src/components/Form/src/componentMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ import {
ElTimeSelect,
ElTransfer,
ElAutocomplete,
ElDivider
ElDivider,
ElRadio
} from 'element-plus'
import { InputPassword } from '@/components/InputPassword'
import { Editor } from '@/components/Editor'
import { ComponentName } from '@/types/components'

const componentMap: Recordable<Component, ComponentName> = {
Radio: ElRadioGroup,
Radio: ElRadio,
// RadioGroup: ElRadioGroup,
Checkbox: ElCheckboxGroup,
CheckboxButton: ElCheckboxGroup,
Input: ElInput,
Expand Down
6 changes: 5 additions & 1 deletion src/components/Form/src/components/useRenderRadio.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { FormSchema } from '@/types/form'
import { ElRadio, ElRadioButton } from 'element-plus'
import { defineComponent } from 'vue'
import { ComponentNameEnum } from '@/types/components.d'

export const useRenderRadio = () => {
const renderRadioOptions = (item: FormSchema) => {
const renderRadioOptions = (
item: FormSchema,
type?: ComponentNameEnum.RADIO | ComponentNameEnum.RADIO_BUTTON = ComponentNameEnum.RADIO
) => {
// 如果有别名,就取别名
const labelAlias = item?.componentProps?.optionsAlias?.labelField
const valueAlias = item?.componentProps?.optionsAlias?.valueField
Expand Down
10 changes: 5 additions & 5 deletions src/components/Form/src/components/useRenderSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export const useRenderSelect = () => {
const componentsProps = item.componentProps as SelectComponentProps
const optionGroupDefaultSlot = componentsProps.slots?.optionGroupDefault
// 如果有别名,就取别名
const labelAlias = componentsProps?.labelAlias
const keyAlias = componentsProps?.keyAlias
const labelAlias = componentsProps?.props?.label
const keyAlias = componentsProps?.props?.key
return componentsProps?.options?.map((option) => {
if (option?.options?.length) {
return optionGroupDefaultSlot ? (
Expand All @@ -34,9 +34,9 @@ export const useRenderSelect = () => {
const renderSelectOptionItem = (item: FormSchema, option: SelectOption) => {
// 如果有别名,就取别名
const componentsProps = item.componentProps as SelectComponentProps
const labelAlias = componentsProps?.labelAlias
const valueAlias = componentsProps?.valueAlias
const keyAlias = componentsProps?.keyAlias
const labelAlias = componentsProps?.props?.label
const valueAlias = componentsProps?.props?.value
const keyAlias = componentsProps?.props?.key
const optionDefaultSlot = componentsProps.slots?.optionDefault

return (
Expand Down
6 changes: 3 additions & 3 deletions src/components/Form/src/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PlaceholderMoel } from './types'
import { FormSchema } from '@/types/form.d'
import { ColProps, ComponentNameEnum } from '@/types/components.d'
import { isFunction } from '@/utils/is'
import { firstUpperCase } from '@/utils'
import { firstUpperCase, humpToDash } from '@/utils'

const { t } = useI18n()

Expand Down Expand Up @@ -123,11 +123,11 @@ export const setItemComponentSlots = (slotsProps: Recordable = {}): Recordable =
for (const key in slotsProps) {
if (slotsProps[key]) {
if (isFunction(slotsProps[key])) {
slotObj[key] = (...args: any[]) => {
slotObj[humpToDash(key)] = (...args: any[]) => {
return slotsProps[key]?.(...args)
}
} else {
slotObj[key] = () => {
slotObj[humpToDash(key)] = () => {
return slotsProps[key]
}
}
Expand Down
66 changes: 49 additions & 17 deletions src/types/components.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CSSProperties } from 'vue'
import { CSSProperties, VNodeProps, VNode } from 'vue'
import {
InputProps,
AutocompleteProps,
Expand Down Expand Up @@ -148,7 +148,7 @@ export interface InputNumberComponentProps {
style?: CSSProperties
}

interface SelectOption {
export interface SelectOption {
label?: string
disabled?: boolean
value?: any
Expand Down Expand Up @@ -208,19 +208,14 @@ export interface SelectComponentProps {
| 'right-end'
maxCollapseTags?: number
/**
* label别名
* 数据源的字段别名
*/
labelAlias?: string

/**
* value别名
*/
valueAlias?: string

/**
* key别名
*/
keyAlias?: string
props?: {
key?: string
value?: string
label?: string
children?: string
}
on?: {
change?: (value: string | number | boolean | Object) => void
visibleChange?: (visible: boolean) => void
Expand Down Expand Up @@ -390,14 +385,17 @@ export interface ColorPickerComponentProps {

export interface TransferComponentProps {
value?: any[]
data?: Array<{ key; label; disabled }>
data?: any[]
filterable?: boolean
filterPlaceholder?: string
filterMethod?: (query: string, item: any) => boolean
targetOrder?: string
titles?: string[]
buttonTexts?: string[]
renderContent?: (h: any, option: any) => JSX.Element
renderContent?: (
h: (type: string, props: VNodeProps | null, children?: string) => VNode,
option: any
) => JSX.Element
format?: {
noChecked?: string
hasChecked?: string
Expand All @@ -411,7 +409,11 @@ export interface TransferComponentProps {
rightDefaultChecked?: any[]
validateEvent?: boolean
on?: {
change?: (value: any[]) => void
change?: (
value: number | string,
direction: 'left' | 'right',
movedKeys: string[] | number[]
) => void
leftCheckChange?: (value: any[]) => void
rightCheckChange?: (value: any[]) => void
}
Expand All @@ -423,6 +425,36 @@ export interface TransferComponentProps {
style?: CSSProperties
}

export interface RadioOption {
label?: string
value?: string | number | boolean
disabled?: boolean
[key: string]: any
}
export interface RadioComponentProps {
value?: string | number | boolean
label?: string | number | boolean
disabled?: boolean
border?: boolean
size?: ElementPlusSize
options?: RadioOption[]
/**
* 数据源的字段别名
*/
props: {
label?: string
value?: string
disabled?: string
}
name?: string
on?: {
change?: (value: string | number | boolean) => void
}
slots?: {
default?: (...args: any[]) => JSX.Element | null
}
}

export interface ColProps {
span?: number
xs?: number
Expand Down
26 changes: 15 additions & 11 deletions src/types/form.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
SwitchComponentProps,
RateComponentProps,
ColorPickerComponentProps,
TransferComponentProps
TransferComponentProps,
RadioComponentProps
} from '@/types/components'
import { FormValueType, FormValueType } from '@/types/form'
import type { AxiosPromise } from 'axios'
Expand All @@ -36,26 +37,28 @@ export type FormItemProps = {
}

// 定义联合类型和条件类型
type ComponentPropsForComponent<T extends ComponentName> = T extends 'input'
type ComponentPropsForComponent<T extends ComponentName> = T extends 'Input'
? InputComponentProps
: T extends 'autocomplete'
: T extends 'Autocomplete'
? AutocompleteComponentProps
: T extends 'inputNumber'
: T extends 'InputNumber'
? InputNumberComponentProps
: T extends 'select'
: T extends 'Select'
? SelectComponentProps
: T extends 'selectV2'
: T extends 'SelectV2'
? SelectV2ComponentProps
: T extends 'cascader'
: T extends 'Cascader'
? CascaderComponentProps
: T extends 'switch'
: T extends 'Switch'
? SwitchComponentProps
: T extends 'rate'
: T extends 'Rate'
? RateComponentProps
: T extends 'colorPicker'
: T extends 'ColorPicker'
? ColorPickerComponentProps
: T extends 'transfer'
: T extends 'Transfer'
? TransferComponentProps
: T extends 'Radio'
? RadioComponentProps
: any

export interface FormSchema {
Expand Down Expand Up @@ -93,6 +96,7 @@ export interface FormSchema {
| RateComponentProps
| ColorPickerComponentProps
| TransferComponentProps
| RadioComponentProps

/**
* formItem组件属性,具体可以查看element-plus文档
Expand Down
Loading

0 comments on commit 83513d5

Please sign in to comment.