diff --git a/src/components/Form/src/Form.vue b/src/components/Form/src/Form.vue index 84e6e03..c3a585a 100644 --- a/src/components/Form/src/Form.vue +++ b/src/components/Form/src/Form.vue @@ -125,12 +125,15 @@ export default defineComponent({ } } - const getOptions = async (fn: Function, field: string) => { + const getOptions = async (fn: Function, item: FormSchema) => { const options = await fn() setSchema([ { - field, - path: 'componentProps.options', + field: item.field, + path: + item.component === ComponentNameEnum.TREE_SELECT + ? 'componentProps.data' + : 'componentProps.options', value: options } ]) @@ -221,7 +224,7 @@ export default defineComponent({ // 如果有optionApi,优先使用optionApi if (item.optionApi) { // 内部自动调用接口,不影响其他渲染 - getOptions(item.optionApi, item.field) + getOptions(item.optionApi, item) } const formItemSlots: Recordable = { default: () => { diff --git a/src/components/Form/src/helper/componentMap.ts b/src/components/Form/src/helper/componentMap.ts index 6f7559a..3cb8e10 100644 --- a/src/components/Form/src/helper/componentMap.ts +++ b/src/components/Form/src/helper/componentMap.ts @@ -16,7 +16,8 @@ import { ElTimeSelect, ElTransfer, ElAutocomplete, - ElDivider + ElDivider, + ElTreeSelect } from 'element-plus' import { InputPassword } from '@/components/InputPassword' import { Editor } from '@/components/Editor' @@ -43,7 +44,8 @@ const componentMap: Recordable = { TimeSelect: ElTimeSelect, SelectV2: ElSelectV2, InputPassword: InputPassword, - Editor: Editor + Editor: Editor, + TreeSelect: ElTreeSelect } export { componentMap } diff --git a/src/components/Form/src/types/index.ts b/src/components/Form/src/types/index.ts index cb1f1a8..277071c 100644 --- a/src/components/Form/src/types/index.ts +++ b/src/components/Form/src/types/index.ts @@ -38,7 +38,8 @@ export enum ComponentNameEnum { TIME_SELECT = 'TimeSelect', SELECT_V2 = 'SelectV2', INPUT_PASSWORD = 'InputPassword', - EDITOR = 'Editor' + EDITOR = 'Editor', + TREE_SELECT = 'TreeSelect' } type CamelCaseComponentName = keyof typeof ComponentNameEnum extends infer K @@ -52,7 +53,6 @@ type CamelCaseComponentName = keyof typeof ComponentNameEnum extends infer K export type ComponentName = CamelCaseComponentName export interface InputComponentProps { - ref?: any maxlength?: number | string minlength?: number | string showWordLimit?: boolean @@ -98,7 +98,6 @@ export interface InputComponentProps { } export interface AutocompleteComponentProps { - ref?: any placeholder?: string clearable?: boolean disabled?: boolean @@ -131,7 +130,6 @@ export interface AutocompleteComponentProps { } export interface InputNumberComponentProps { - ref?: any min?: number max?: number step?: number @@ -166,7 +164,6 @@ export interface SelectOption { } export interface SelectComponentProps { - ref?: any multiple?: boolean disabled?: boolean valueKey?: string @@ -244,7 +241,6 @@ export interface SelectComponentProps { } export interface SelectV2ComponentProps { - ref?: any multiple?: boolean disabled?: boolean valueKey?: string @@ -289,7 +285,6 @@ export interface SelectV2ComponentProps { } export interface CascaderComponentProps { - ref?: any options?: Record[] props?: CascaderProps size?: ElementPlusSize @@ -324,7 +319,6 @@ export interface CascaderComponentProps { } export interface SwitchComponentProps { - ref?: any disabled?: boolean loading?: boolean size?: ElementPlusSize @@ -346,7 +340,6 @@ export interface SwitchComponentProps { } export interface RateComponentProps { - ref?: any max?: number size?: ElementPlusSize disabled?: boolean @@ -374,7 +367,6 @@ export interface RateComponentProps { } export interface ColorPickerComponentProps { - ref?: any disabled?: boolean size?: ElementPlusSize showAlpha?: boolean @@ -392,7 +384,6 @@ export interface ColorPickerComponentProps { } export interface TransferComponentProps { - ref?: any data?: any[] filterable?: boolean filterPlaceholder?: string @@ -443,7 +434,6 @@ export interface RadioOption { [key: string]: any } export interface RadioGroupComponentProps { - ref?: any size?: ElementPlusSize disabled?: boolean textColor?: string @@ -471,7 +461,6 @@ export interface RadioGroupComponentProps { } export interface RadioButtonComponentProps { - ref?: any size?: ElementPlusSize disabled?: boolean textColor?: string @@ -517,7 +506,6 @@ export interface CheckboxOption { } export interface CheckboxGroupComponentProps { - ref?: any size?: ElementPlusSize disabled?: boolean min?: number @@ -546,7 +534,6 @@ export interface CheckboxGroupComponentProps { } export interface DividerComponentProps { - ref?: any min?: number max?: number disabled?: boolean @@ -578,7 +565,6 @@ export interface DividerComponentProps { } export interface DatePickerComponentProps { - ref?: any readonly?: boolean disabled?: boolean size?: ElementPlusSize @@ -630,7 +616,6 @@ export interface DatePickerComponentProps { } export interface DateTimePickerComponentProps { - ref?: any readonly?: boolean disabled?: boolean editable?: boolean @@ -671,7 +656,6 @@ export interface DateTimePickerComponentProps { } export interface TimePickerComponentProps { - ref?: any readonly?: boolean disabled?: boolean editable?: boolean @@ -708,7 +692,6 @@ export interface TimePickerComponentProps { } export interface TimeSelectComponentProps { - ref?: any disabled?: boolean editable?: boolean clearable?: boolean @@ -733,7 +716,6 @@ export interface TimeSelectComponentProps { } export interface EditorComponentProps { - ref?: any editorConfig?: IEditorConfig style?: CSSProperties } @@ -755,7 +737,6 @@ export interface FormSetProps { } export interface FormItemProps { - ref?: any labelWidth?: string | number required?: boolean rules?: FormItemRule | FormItemRule[] diff --git a/src/locales/en.ts b/src/locales/en.ts index 23d6cdf..4f2b13f 100644 --- a/src/locales/en.ts +++ b/src/locales/en.ts @@ -287,7 +287,16 @@ export default { // 远程加载 remoteLoading: 'Remote loading', // 聚焦 - focus: 'Focus' + focus: 'Focus', + treeSelect: 'Tree Select', + showCheckbox: 'Show Checkbox', + selectAnyLevel: 'Select Any Level', + multiple: 'Multiple', + filterable: 'Filterable', + // 自定义节点内容 + customContent: 'Custom content', + // 懒加载 + lazyLoad: 'Lazy load' }, guideDemo: { guide: 'Guide', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index 006e3aa..e8f4fb0 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -286,7 +286,14 @@ export default { // 远程加载 remoteLoading: '远程加载', // 聚焦 - focus: '聚焦' + focus: '聚焦', + treeSelect: '树形选择器', + showCheckbox: '显示复选框', + selectAnyLevel: '选择任意级别', + multiple: '多选', + filterable: '可筛选', + customContent: '自定义内容', + lazyLoad: '懒加载' }, guideDemo: { guide: '引导页', diff --git a/src/views/Components/Form/DefaultForm.vue b/src/views/Components/Form/DefaultForm.vue index d400440..bae85b1 100644 --- a/src/views/Components/Form/DefaultForm.vue +++ b/src/views/Components/Form/DefaultForm.vue @@ -368,6 +368,79 @@ const isHoliday = ({ dayjs }) => { return holidays.includes(dayjs.format('YYYY-MM-DD')) } +const treeSelectData = [ + { + value: '1', + label: 'Level one 1', + children: [ + { + value: '1-1', + label: 'Level two 1-1', + children: [ + { + value: '1-1-1', + label: 'Level three 1-1-1' + } + ] + } + ] + }, + { + value: '2', + label: 'Level one 2', + children: [ + { + value: '2-1', + label: 'Level two 2-1', + children: [ + { + value: '2-1-1', + label: 'Level three 2-1-1' + } + ] + }, + { + value: '2-2', + label: 'Level two 2-2', + children: [ + { + value: '2-2-1', + label: 'Level three 2-2-1' + } + ] + } + ] + }, + { + value: '3', + label: 'Level one 3', + children: [ + { + value: '3-1', + label: 'Level two 3-1', + children: [ + { + value: '3-1-1', + label: 'Level three 3-1-1' + } + ] + }, + { + value: '3-2', + label: 'Level two 3-2', + children: [ + { + value: '3-2-1', + label: 'Level three 3-2-1' + } + ] + } + ] + } +] + +let id = 0 + const schema = reactive([ { field: 'field1', @@ -1452,6 +1525,147 @@ const schema = reactive([ const res = await getDictOneApi() return res.data } + }, + { + field: 'field82', + label: `${t('formDemo.treeSelect')}`, + component: 'TreeSelect', + // 远程加载option + optionApi: () => { + return treeSelectData + } + }, + { + field: 'field75', + component: 'Divider', + label: `${t('formDemo.treeSelect')}` + }, + { + field: 'field76', + component: 'TreeSelect', + label: `${t('formDemo.default')}`, + componentProps: { + renderAfterExpand: false, + data: treeSelectData + } + }, + { + field: 'field76', + component: 'TreeSelect', + label: `${t('formDemo.showCheckbox')}`, + componentProps: { + renderAfterExpand: false, + showCheckbox: true, + data: treeSelectData + } + }, + { + field: 'field77', + component: 'TreeSelect', + label: `${t('formDemo.selectAnyLevel')}`, + componentProps: { + renderAfterExpand: false, + showCheckbox: true, + checkStrictly: true, + checkOnClickNode: true, + data: treeSelectData + } + }, + { + field: 'field78', + component: 'TreeSelect', + label: `${t('formDemo.multiple')}`, + componentProps: { + renderAfterExpand: false, + multiple: true, + showCheckbox: true, + checkStrictly: true, + checkOnClickNode: true, + data: treeSelectData + } + }, + { + field: 'field79', + component: 'TreeSelect', + label: `${t('formDemo.filterable')}`, + componentProps: { + renderAfterExpand: false, + multiple: true, + filterable: true, + showCheckbox: true, + checkStrictly: true, + checkOnClickNode: true, + filterNodeMethod: (value, data) => data.label.includes(value), + data: treeSelectData + } + }, + { + field: 'field80', + component: 'TreeSelect', + label: `${t('formDemo.customContent')}`, + componentProps: { + renderAfterExpand: false, + multiple: true, + filterable: true, + showCheckbox: true, + checkStrictly: true, + checkOnClickNode: true, + filterNodeMethod: (value, data) => data.label.includes(value), + slots: { + default: ({ data: { label } }) => { + return ( + <> + {label} + (suffix) + + ) + } + }, + data: treeSelectData + } + }, + { + field: 'field81', + component: 'TreeSelect', + label: `${t('formDemo.lazyLoad')}`, + componentProps: { + renderAfterExpand: false, + lazy: true, + load: (node, resolve) => { + if (node.isLeaf) return resolve([]) + + setTimeout(() => { + resolve([ + { + value: ++id, + label: `lazy load node${id}` + }, + { + value: ++id, + label: `lazy load node${id}`, + isLeaf: true + } + ]) + }, 400) + }, + multiple: true, + filterable: true, + showCheckbox: true, + checkStrictly: true, + checkOnClickNode: true, + filterNodeMethod: (value, data) => data.label.includes(value), + slots: { + default: ({ data: { label } }) => { + return ( + <> + {label} + (suffix) + + ) + } + }, + data: treeSelectData + } } ])