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()
|
||||
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: () => {
|
||||
|
|
|
@ -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<Component, ComponentName> = {
|
|||
TimeSelect: ElTimeSelect,
|
||||
SelectV2: ElSelectV2,
|
||||
InputPassword: InputPassword,
|
||||
Editor: Editor
|
||||
Editor: Editor,
|
||||
TreeSelect: ElTreeSelect
|
||||
}
|
||||
|
||||
export { componentMap }
|
||||
|
|
|
@ -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<string, unknown>[]
|
||||
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[]
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -286,7 +286,14 @@ export default {
|
|||
// 远程加载
|
||||
remoteLoading: '远程加载',
|
||||
// 聚焦
|
||||
focus: '聚焦'
|
||||
focus: '聚焦',
|
||||
treeSelect: '树形选择器',
|
||||
showCheckbox: '显示复选框',
|
||||
selectAnyLevel: '选择任意级别',
|
||||
multiple: '多选',
|
||||
filterable: '可筛选',
|
||||
customContent: '自定义内容',
|
||||
lazyLoad: '懒加载'
|
||||
},
|
||||
guideDemo: {
|
||||
guide: '引导页',
|
||||
|
|
|
@ -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<FormSchema[]>([
|
||||
{
|
||||
field: 'field1',
|
||||
|
@ -1452,6 +1525,147 @@ const schema = reactive<FormSchema[]>([
|
|||
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}
|
||||
<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>
|
||||
|
|
Loading…
Reference in New Issue