wip: Form改造

This commit is contained in:
kailong321200875 2023-05-17 14:53:53 +08:00
parent 4d04734e13
commit c5b545d2c7
3 changed files with 255 additions and 90 deletions

View File

@ -1,5 +1,13 @@
import { CSSProperties } from 'vue' import { CSSProperties } from 'vue'
import { InputProps, AutocompleteProps, InputNumberProps } from 'element-plus' import {
InputProps,
AutocompleteProps,
InputNumberProps,
CascaderProps,
CascaderNode,
CascaderValue
} from 'element-plus'
import { ElementPlusSize, ElementPlusInfoType } from './elementPlus.d'
export enum ComponentNameEnum { export enum ComponentNameEnum {
RADIO = 'Radio', RADIO = 'Radio',
@ -46,7 +54,7 @@ export interface InputComponentProps {
parser?: (value: string) => string parser?: (value: string) => string
showPassword?: boolean showPassword?: boolean
disabled?: boolean disabled?: boolean
size?: InputProps['size'] size?: ElementPlusSize
prefixIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element) prefixIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element)
suffixIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element) suffixIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element)
type?: InputProps['type'] type?: InputProps['type']
@ -121,7 +129,7 @@ export interface InputNumberComponentProps {
step?: number step?: number
stepStrictly?: boolean stepStrictly?: boolean
precision?: number precision?: number
size?: InputNumberProps['size'] size?: ElementPlusSize
readonly?: boolean readonly?: boolean
disabled?: boolean disabled?: boolean
controls?: boolean controls?: boolean
@ -154,7 +162,7 @@ export interface SelectComponentProps {
multiple?: boolean multiple?: boolean
disabled?: boolean disabled?: boolean
valueKey?: string valueKey?: string
size?: InputNumberProps['size'] size?: ElementPlusSize
clearable?: boolean clearable?: boolean
collapseTags?: boolean collapseTags?: boolean
collapseTagsTooltip?: number collapseTagsTooltip?: number
@ -230,7 +238,6 @@ export interface SelectComponentProps {
} }
options?: SelectOption[] options?: SelectOption[]
style?: CSSProperties style?: CSSProperties
style?: CSSProperties
} }
export interface SelectV2ComponentProps { export interface SelectV2ComponentProps {
@ -238,7 +245,7 @@ export interface SelectV2ComponentProps {
multiple?: boolean multiple?: boolean
disabled?: boolean disabled?: boolean
valueKey?: string valueKey?: string
size?: InputNumberProps['size'] size?: ElementPlusSize
clearable?: boolean clearable?: boolean
clearIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element) clearIcon?: string | JSX.Element | ((formData: any) => string | JSX.Element)
collapseTags?: boolean collapseTags?: boolean
@ -278,6 +285,144 @@ export interface SelectV2ComponentProps {
style?: CSSProperties style?: CSSProperties
} }
export interface CascaderComponentProps {
value?: string | number | string[] | number[] | any
options?: Record<string, unknown>[]
props?: CascaderProps
size?: ElementPlusSize
placeholder?: string
disabled?: boolean
clearable?: boolean
showAllLevels?: boolean
collapseTags?: boolean
collapseTagsTooltip?: boolean
separator?: string
filterable?: boolean
filterMethod?: (node: CascaderNode, keyword: string) => boolean
debounce?: number
beforeFilter?: (value: string) => boolean
popperClass?: string
teleported?: boolean
tagType?: ElementPlusInfoType
validateEvent?: boolean
on?: {
change?: (value: CascaderValue) => void
expandChange?: (value: CascaderValue) => void
blur?: (event: FocusEvent) => void
focus?: (event: FocusEvent) => void
visibleChange?: (value: boolean) => void
removeTag?: (value: CascaderNode['valueByOption']) => void
}
slots?: {
default?: (formData: any, { node: any, data: any }) => JSX.Element | null
empty?: JSX.Element | null | ((formData: any) => JSX.Element | null)
}
style?: CSSProperties
}
export interface SwitchComponentProps {
value?: boolean | string | number
disabled?: boolean
loading?: boolean
size?: ElementPlusSize
width?: number | string
inlinePrompt?: boolean
activeIcon?: string | JSX.Element | null | ((formData: any) => string | JSX.Element | null)
inactiveIcon?: string | JSX.Element | null | ((formData: any) => string | JSX.Element | null)
activeText?: string
inactiveText?: string
activeValue?: boolean | string | number
inactiveValue?: boolean | string | number
name?: string
validateEvent?: boolean
beforeChange?: (value: boolean) => boolean | Promise<boolean>
on?: {
change?: (value: boolean | string | number) => void
}
style?: CSSProperties
}
export interface RateComponentProps {
value?: number
max?: number
size?: ElementPlusSize
disabled?: boolean
allowHalf?: boolean
lowThreshold?: number
highThreshold?: number
colors?: string[] | Record<number, string>
voidColor?: string
disabledVoidColor?: string
icons?: string[] | JSX.Element[] | Record<number, string | JSX.Element>
voidIcon?: string | JSX.Element
disabledVoidIcon?: string | JSX.Element
showText?: boolean
showScore?: boolean
textColor?: string
texts?: string[]
scoreTemplate?: string
clearable?: boolean
id?: string
label?: string
on?: {
change?: (value: number) => void
}
style?: CSSProperties
}
export interface ColorPickerComponentProps {
value?: string
disabled?: boolean
size?: ElementPlusSize
showAlpha?: boolean
colorFormat?: 'hsl' | 'hsv' | 'hex' | 'rgb' | 'hex' | 'rgb'
predefine?: string[]
validateEvent?: boolean
tabindex?: number | string
label?: string
id?: string
on?: {
change?: (value: string) => void
activeChange?: (value: string) => void
}
style?: CSSProperties
}
export interface TransferComponentProps {
value?: any[]
data?: Array<{ key; label; disabled }>
filterable?: boolean
filterPlaceholder?: string
filterMethod?: (query: string, item: any) => boolean
targetOrder?: string
titles?: string[]
buttonTexts?: string[]
renderContent?: (h: any, option: any) => JSX.Element
format?: {
noChecked?: string
hasChecked?: string
}
props?: {
label?: string
key?: string
disabled?: string
}
leftDefaultChecked?: any[]
rightDefaultChecked?: any[]
validateEvent?: boolean
on?: {
change?: (value: any[]) => void
leftCheckChange?: (value: any[]) => void
rightCheckChange?: (value: any[]) => void
}
slots?: {
default?: (formData: any, data: { option: any }) => JSX.Element | null
leftFooter?: (formData: any) => JSX.Element | null
rightFooter?: (formData: any) => JSX.Element | null
}
style?: CSSProperties
}
export interface ColProps { export interface ColProps {
span?: number span?: number
xs?: number xs?: number

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

@ -7,7 +7,12 @@ import {
AutocompleteComponentProps, AutocompleteComponentProps,
InputNumberComponentProps, InputNumberComponentProps,
SelectComponentProps, SelectComponentProps,
SelectV2ComponentProps SelectV2ComponentProps,
CascaderComponentProps,
SwitchComponentProps,
RateComponentProps,
ColorPickerComponentProps,
TransferComponentProps
} 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'
@ -60,6 +65,11 @@ export interface FormSchema {
| InputNumberComponentProps | InputNumberComponentProps
| SelectComponentProps | SelectComponentProps
| SelectV2ComponentProps | SelectV2ComponentProps
| CascaderComponentProps
| SwitchComponentProps
| RateComponentProps
| ColorPickerComponentProps
| TransferComponentProps
/** /**
* formItem组件属性element-plus文档 * formItem组件属性element-plus文档

View File

@ -61,13 +61,13 @@ onMounted(() => {
}) })
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const options = ref<ComponentOptions[]>( const options = ref(
Array.from({ length: 1000 }).map((_, idx) => ({ Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`, value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}` label: `${initials[idx % 10]}${idx}`
})) }))
) )
const options2 = ref<ComponentOptions[]>( const options2 = ref(
Array.from({ length: 10 }).map((_, idx) => { Array.from({ length: 10 }).map((_, idx) => {
const label = idx + 1 const label = idx + 1
return { return {
@ -81,7 +81,7 @@ const options2 = ref<ComponentOptions[]>(
}) })
) )
const options3: ComponentOptions[] = [ const options3 = [
{ {
value: 'guide', value: 'guide',
label: 'Guide', label: 'Guide',
@ -756,88 +756,98 @@ const schema = reactive<FormSchema[]>([
field: 'field23', field: 'field23',
label: t('formDemo.cascader'), label: t('formDemo.cascader'),
component: 'Divider' component: 'Divider'
},
{
field: 'field24',
label: t('formDemo.default'),
component: 'Cascader',
componentProps: {
options: options3,
props: {
multiple: true
}
}
},
{
field: 'field25',
label: t('formDemo.slot'),
component: 'Cascader',
componentProps: {
options: options3,
slots: {
default: (_, { data, node }) => {
return (
<>
<span>{data.label}</span>
{!node.isLeaf ? <span> ({data.children.length}) </span> : null}
</>
)
}
}
}
},
{
field: 'field26',
label: t('formDemo.switch'),
component: 'Divider'
},
{
field: 'field27',
label: t('formDemo.default'),
component: 'Switch',
value: false
},
{
field: 'field28',
label: t('formDemo.icon'),
component: 'Switch',
value: false,
componentProps: {
activeIcon: useIcon({ icon: 'ep:check' }),
inactiveIcon: useIcon({ icon: 'ep:close' })
}
},
{
field: 'field29',
label: t('formDemo.rate'),
component: 'Divider'
},
{
field: 'field30',
label: t('formDemo.default'),
component: 'Rate',
value: 0
},
{
field: 'field31',
label: t('formDemo.icon'),
component: 'Rate',
value: null,
componentProps: {
voidIcon: useIcon({ icon: 'ep:chat-round' }),
icons: [
useIcon({ icon: 'ep:chat-round' }),
useIcon({ icon: 'ep:chat-line-round' }),
useIcon({ icon: 'ep:chat-dot-round' })
]
}
},
{
field: 'field32',
label: t('formDemo.colorPicker'),
component: 'Divider'
},
{
field: 'field33',
label: t('formDemo.default'),
component: 'ColorPicker'
},
{
field: 'field34',
label: t('formDemo.transfer'),
component: 'Divider'
} }
// { // {
// field: 'field24',
// label: t('formDemo.default'),
// component: 'Cascader',
// componentProps: {
// options: options3
// }
// },
// {
// field: 'field25',
// label: t('formDemo.slot'),
// component: 'Cascader',
// componentProps: {
// options: options3,
// slots: {
// default: true
// }
// }
// },
// {
// field: 'field26',
// label: t('formDemo.switch'),
// component: 'Divider'
// },
// {
// field: 'field27',
// label: t('formDemo.default'),
// component: 'Switch',
// value: false
// },
// {
// field: 'field28',
// label: t('formDemo.icon'),
// component: 'Switch',
// value: false,
// componentProps: {
// activeIcon: useIcon({ icon: 'ep:check' }),
// inactiveIcon: useIcon({ icon: 'ep:close' })
// }
// },
// {
// field: 'field29',
// label: t('formDemo.rate'),
// component: 'Divider'
// },
// {
// field: 'field30',
// label: t('formDemo.default'),
// component: 'Rate',
// value: null
// },
// {
// field: 'field31',
// label: t('formDemo.icon'),
// component: 'Rate',
// value: null,
// componentProps: {
// voidIcon: useIcon({ icon: 'ep:chat-round' }),
// icons: [
// useIcon({ icon: 'ep:chat-round' }),
// useIcon({ icon: 'ep:chat-line-round' }),
// useIcon({ icon: 'ep:chat-dot-round' })
// ]
// }
// },
// {
// field: 'field32',
// label: t('formDemo.colorPicker'),
// component: 'Divider'
// },
// {
// field: 'field33',
// label: t('formDemo.default'),
// component: 'ColorPicker'
// },
// {
// field: 'field34',
// label: t('formDemo.transfer'),
// component: 'Divider'
// },
// {
// field: 'field35', // field: 'field35',
// label: t('formDemo.default'), // label: t('formDemo.default'),
// component: 'Transfer', // component: 'Transfer',