feat: 新增TreeSelect表单项
This commit is contained in:
parent
9a78ac977e
commit
de0cb43566
|
@ -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()
|
const options = await fn()
|
||||||
setSchema([
|
setSchema([
|
||||||
{
|
{
|
||||||
field,
|
field: item.field,
|
||||||
path: 'componentProps.options',
|
path:
|
||||||
|
item.component === ComponentNameEnum.TREE_SELECT
|
||||||
|
? 'componentProps.data'
|
||||||
|
: 'componentProps.options',
|
||||||
value: options
|
value: options
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
@ -221,7 +224,7 @@ export default defineComponent({
|
||||||
// 如果有optionApi,优先使用optionApi
|
// 如果有optionApi,优先使用optionApi
|
||||||
if (item.optionApi) {
|
if (item.optionApi) {
|
||||||
// 内部自动调用接口,不影响其他渲染
|
// 内部自动调用接口,不影响其他渲染
|
||||||
getOptions(item.optionApi, item.field)
|
getOptions(item.optionApi, item)
|
||||||
}
|
}
|
||||||
const formItemSlots: Recordable = {
|
const formItemSlots: Recordable = {
|
||||||
default: () => {
|
default: () => {
|
||||||
|
|
|
@ -16,7 +16,8 @@ import {
|
||||||
ElTimeSelect,
|
ElTimeSelect,
|
||||||
ElTransfer,
|
ElTransfer,
|
||||||
ElAutocomplete,
|
ElAutocomplete,
|
||||||
ElDivider
|
ElDivider,
|
||||||
|
ElTreeSelect
|
||||||
} from 'element-plus'
|
} from 'element-plus'
|
||||||
import { InputPassword } from '@/components/InputPassword'
|
import { InputPassword } from '@/components/InputPassword'
|
||||||
import { Editor } from '@/components/Editor'
|
import { Editor } from '@/components/Editor'
|
||||||
|
@ -43,7 +44,8 @@ const componentMap: Recordable<Component, ComponentName> = {
|
||||||
TimeSelect: ElTimeSelect,
|
TimeSelect: ElTimeSelect,
|
||||||
SelectV2: ElSelectV2,
|
SelectV2: ElSelectV2,
|
||||||
InputPassword: InputPassword,
|
InputPassword: InputPassword,
|
||||||
Editor: Editor
|
Editor: Editor,
|
||||||
|
TreeSelect: ElTreeSelect
|
||||||
}
|
}
|
||||||
|
|
||||||
export { componentMap }
|
export { componentMap }
|
||||||
|
|
|
@ -38,7 +38,8 @@ export enum ComponentNameEnum {
|
||||||
TIME_SELECT = 'TimeSelect',
|
TIME_SELECT = 'TimeSelect',
|
||||||
SELECT_V2 = 'SelectV2',
|
SELECT_V2 = 'SelectV2',
|
||||||
INPUT_PASSWORD = 'InputPassword',
|
INPUT_PASSWORD = 'InputPassword',
|
||||||
EDITOR = 'Editor'
|
EDITOR = 'Editor',
|
||||||
|
TREE_SELECT = 'TreeSelect'
|
||||||
}
|
}
|
||||||
|
|
||||||
type CamelCaseComponentName = keyof typeof ComponentNameEnum extends infer K
|
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 type ComponentName = CamelCaseComponentName
|
||||||
|
|
||||||
export interface InputComponentProps {
|
export interface InputComponentProps {
|
||||||
ref?: any
|
|
||||||
maxlength?: number | string
|
maxlength?: number | string
|
||||||
minlength?: number | string
|
minlength?: number | string
|
||||||
showWordLimit?: boolean
|
showWordLimit?: boolean
|
||||||
|
@ -98,7 +98,6 @@ export interface InputComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AutocompleteComponentProps {
|
export interface AutocompleteComponentProps {
|
||||||
ref?: any
|
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
clearable?: boolean
|
clearable?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
@ -131,7 +130,6 @@ export interface AutocompleteComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InputNumberComponentProps {
|
export interface InputNumberComponentProps {
|
||||||
ref?: any
|
|
||||||
min?: number
|
min?: number
|
||||||
max?: number
|
max?: number
|
||||||
step?: number
|
step?: number
|
||||||
|
@ -166,7 +164,6 @@ export interface SelectOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelectComponentProps {
|
export interface SelectComponentProps {
|
||||||
ref?: any
|
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
valueKey?: string
|
valueKey?: string
|
||||||
|
@ -244,7 +241,6 @@ export interface SelectComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelectV2ComponentProps {
|
export interface SelectV2ComponentProps {
|
||||||
ref?: any
|
|
||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
valueKey?: string
|
valueKey?: string
|
||||||
|
@ -289,7 +285,6 @@ export interface SelectV2ComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CascaderComponentProps {
|
export interface CascaderComponentProps {
|
||||||
ref?: any
|
|
||||||
options?: Record<string, unknown>[]
|
options?: Record<string, unknown>[]
|
||||||
props?: CascaderProps
|
props?: CascaderProps
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
|
@ -324,7 +319,6 @@ export interface CascaderComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SwitchComponentProps {
|
export interface SwitchComponentProps {
|
||||||
ref?: any
|
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
|
@ -346,7 +340,6 @@ export interface SwitchComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RateComponentProps {
|
export interface RateComponentProps {
|
||||||
ref?: any
|
|
||||||
max?: number
|
max?: number
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
@ -374,7 +367,6 @@ export interface RateComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColorPickerComponentProps {
|
export interface ColorPickerComponentProps {
|
||||||
ref?: any
|
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
showAlpha?: boolean
|
showAlpha?: boolean
|
||||||
|
@ -392,7 +384,6 @@ export interface ColorPickerComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TransferComponentProps {
|
export interface TransferComponentProps {
|
||||||
ref?: any
|
|
||||||
data?: any[]
|
data?: any[]
|
||||||
filterable?: boolean
|
filterable?: boolean
|
||||||
filterPlaceholder?: string
|
filterPlaceholder?: string
|
||||||
|
@ -443,7 +434,6 @@ export interface RadioOption {
|
||||||
[key: string]: any
|
[key: string]: any
|
||||||
}
|
}
|
||||||
export interface RadioGroupComponentProps {
|
export interface RadioGroupComponentProps {
|
||||||
ref?: any
|
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
textColor?: string
|
textColor?: string
|
||||||
|
@ -471,7 +461,6 @@ export interface RadioGroupComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RadioButtonComponentProps {
|
export interface RadioButtonComponentProps {
|
||||||
ref?: any
|
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
textColor?: string
|
textColor?: string
|
||||||
|
@ -517,7 +506,6 @@ export interface CheckboxOption {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CheckboxGroupComponentProps {
|
export interface CheckboxGroupComponentProps {
|
||||||
ref?: any
|
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
min?: number
|
min?: number
|
||||||
|
@ -546,7 +534,6 @@ export interface CheckboxGroupComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DividerComponentProps {
|
export interface DividerComponentProps {
|
||||||
ref?: any
|
|
||||||
min?: number
|
min?: number
|
||||||
max?: number
|
max?: number
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
@ -578,7 +565,6 @@ export interface DividerComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DatePickerComponentProps {
|
export interface DatePickerComponentProps {
|
||||||
ref?: any
|
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
size?: ElementPlusSize
|
size?: ElementPlusSize
|
||||||
|
@ -630,7 +616,6 @@ export interface DatePickerComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DateTimePickerComponentProps {
|
export interface DateTimePickerComponentProps {
|
||||||
ref?: any
|
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
editable?: boolean
|
editable?: boolean
|
||||||
|
@ -671,7 +656,6 @@ export interface DateTimePickerComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimePickerComponentProps {
|
export interface TimePickerComponentProps {
|
||||||
ref?: any
|
|
||||||
readonly?: boolean
|
readonly?: boolean
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
editable?: boolean
|
editable?: boolean
|
||||||
|
@ -708,7 +692,6 @@ export interface TimePickerComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimeSelectComponentProps {
|
export interface TimeSelectComponentProps {
|
||||||
ref?: any
|
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
editable?: boolean
|
editable?: boolean
|
||||||
clearable?: boolean
|
clearable?: boolean
|
||||||
|
@ -733,7 +716,6 @@ export interface TimeSelectComponentProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorComponentProps {
|
export interface EditorComponentProps {
|
||||||
ref?: any
|
|
||||||
editorConfig?: IEditorConfig
|
editorConfig?: IEditorConfig
|
||||||
style?: CSSProperties
|
style?: CSSProperties
|
||||||
}
|
}
|
||||||
|
@ -755,7 +737,6 @@ export interface FormSetProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FormItemProps {
|
export interface FormItemProps {
|
||||||
ref?: any
|
|
||||||
labelWidth?: string | number
|
labelWidth?: string | number
|
||||||
required?: boolean
|
required?: boolean
|
||||||
rules?: FormItemRule | FormItemRule[]
|
rules?: FormItemRule | FormItemRule[]
|
||||||
|
|
|
@ -287,7 +287,16 @@ export default {
|
||||||
// 远程加载
|
// 远程加载
|
||||||
remoteLoading: 'Remote loading',
|
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: {
|
guideDemo: {
|
||||||
guide: 'Guide',
|
guide: 'Guide',
|
||||||
|
|
|
@ -286,7 +286,14 @@ export default {
|
||||||
// 远程加载
|
// 远程加载
|
||||||
remoteLoading: '远程加载',
|
remoteLoading: '远程加载',
|
||||||
// 聚焦
|
// 聚焦
|
||||||
focus: '聚焦'
|
focus: '聚焦',
|
||||||
|
treeSelect: '树形选择器',
|
||||||
|
showCheckbox: '显示复选框',
|
||||||
|
selectAnyLevel: '选择任意级别',
|
||||||
|
multiple: '多选',
|
||||||
|
filterable: '可筛选',
|
||||||
|
customContent: '自定义内容',
|
||||||
|
lazyLoad: '懒加载'
|
||||||
},
|
},
|
||||||
guideDemo: {
|
guideDemo: {
|
||||||
guide: '引导页',
|
guide: '引导页',
|
||||||
|
|
|
@ -368,6 +368,79 @@ const isHoliday = ({ dayjs }) => {
|
||||||
return holidays.includes(dayjs.format('YYYY-MM-DD'))
|
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<FormSchema[]>([
|
const schema = reactive<FormSchema[]>([
|
||||||
{
|
{
|
||||||
field: 'field1',
|
field: 'field1',
|
||||||
|
@ -1452,6 +1525,147 @@ const schema = reactive<FormSchema[]>([
|
||||||
const res = await getDictOneApi()
|
const res = await getDictOneApi()
|
||||||
return res.data
|
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}
|
||||||
|
<span style="color: gray">(suffix)</span>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
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}
|
||||||
|
<span style="color: gray">(suffix)</span>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: treeSelectData
|
||||||
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in New Issue