feat(VForm): Add VForm component

This commit is contained in:
kailong321200875
2021-12-26 17:32:33 +08:00
parent d16a5aa75e
commit 448ac5293e
11 changed files with 585 additions and 149 deletions

View File

@@ -12,6 +12,8 @@ import {
setModel
} from './helper'
import { useRenderSelect } from './components/useRenderSelect'
import { useRenderRadio } from './components/useRenderRadio'
import { useRenderChcekbox } from './components/useRenderChcekbox'
export default defineComponent({
name: 'VForm',
@@ -93,7 +95,11 @@ export default defineComponent({
const slotsMap: Recordable = {
...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
}
if (item?.component !== 'SelectV2' && item.options) {
if (
item?.component !== 'SelectV2' &&
item?.component !== 'Cascader' &&
item?.componentProps?.options
) {
slotsMap.default = () => renderOptions(item)
}
return (
@@ -105,8 +111,9 @@ export default defineComponent({
vModel={formModel[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item)}
{...(notRenderOptions.includes(item?.component as string) && item.options
? { options: item.options || [] }
{...(notRenderOptions.includes(item?.component as string) &&
item?.componentProps?.options
? { options: item?.componentProps?.options || [] }
: {})}
>
{{ ...slotsMap }}
@@ -123,6 +130,14 @@ export default defineComponent({
case 'Select':
const { renderSelectOptions } = useRenderSelect(slots)
return renderSelectOptions(item)
case 'Radio':
case 'RadioButton':
const { renderRadioOptions } = useRenderRadio()
return renderRadioOptions(item)
case 'Checkbox':
case 'CheckboxButton':
const { renderChcekboxOptions } = useRenderChcekbox()
return renderChcekboxOptions(item)
default:
break
}
@@ -142,7 +157,7 @@ export default defineComponent({
}
return () => (
<ElForm ref={formRef} {...getFormBindValue()} model={formModel}>
<ElForm ref={formRef} {...getFormBindValue()} model={formModel} class="v-form">
{{
// 如果需要自定义,就什么都不渲染,而是提供默认插槽
default: () => (isCustom ? getSlot(slots, 'default') : renderWrap())

View File

@@ -22,6 +22,7 @@ import {
const componentMap: Recordable<Component, ComponentName> = {
Radio: ElRadioGroup,
Checkbox: ElCheckboxGroup,
CheckboxButton: ElCheckboxGroup,
Input: ElInput,
Autocomplete: ElAutocomplete,
InputNumber: ElInputNumber,
@@ -36,7 +37,8 @@ const componentMap: Recordable<Component, ComponentName> = {
Transfer: ElTransfer,
Divider: ElDivider,
TimeSelect: ElTimeSelect,
SelectV2: ElSelectV2
SelectV2: ElSelectV2,
RadioButton: ElRadioGroup
}
export { componentMap }

View File

@@ -0,0 +1,20 @@
import { ElCheckbox, ElCheckboxButton } from 'element-plus'
import { defineComponent } from 'vue'
export function useRenderChcekbox() {
function renderChcekboxOptions(item: VFormSchema) {
// 如果有别名,就取别名
const labelAlias = item?.componentProps?.optionsAlias?.labelField
const valueAlias = item?.componentProps?.optionsAlias?.valueField
const Com = (item.component === 'Checkbox' ? ElCheckbox : ElCheckboxButton) as ReturnType<
typeof defineComponent
>
return item?.componentProps?.options?.map((option) => {
return <Com label={option[labelAlias || 'value']}>{option[valueAlias || 'label']}</Com>
})
}
return {
renderChcekboxOptions
}
}

View File

@@ -0,0 +1,20 @@
import { ElRadio, ElRadioButton } from 'element-plus'
import { defineComponent } from 'vue'
export function useRenderRadio() {
function renderRadioOptions(item: VFormSchema) {
// 如果有别名,就取别名
const labelAlias = item?.componentProps?.optionsAlias?.labelField
const valueAlias = item?.componentProps?.optionsAlias?.valueField
const Com = (item.component === 'Radio' ? ElRadio : ElRadioButton) as ReturnType<
typeof defineComponent
>
return item?.componentProps?.options?.map((option) => {
return <Com label={option[labelAlias || 'value']}>{option[valueAlias || 'label']}</Com>
})
}
return {
renderRadioOptions
}
}

View File

@@ -6,11 +6,11 @@ export function useRenderSelect(slots: Slots) {
// 渲染 select options
function renderSelectOptions(item: VFormSchema) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
return item.options?.map((option) => {
const labelAlias = item?.componentProps?.optionsAlias?.labelField
return item?.componentProps?.options?.map((option) => {
if (option?.options?.length) {
return (
<ElOptionGroup label={labelAlias ? option[labelAlias] : option['label']}>
<ElOptionGroup label={option[labelAlias || 'label']}>
{() => {
return option?.options?.map((v) => {
return renderSelectOptionItem(item, v)
@@ -25,19 +25,18 @@ export function useRenderSelect(slots: Slots) {
}
// 渲染 select option item
function renderSelectOptionItem(item: VFormSchema, option: FormOptions) {
function renderSelectOptionItem(item: VFormSchema, option: ComponentOptions) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
const valueAlias = item.optionsField?.valueField
const labelAlias = item?.componentProps?.optionsAlias?.labelField
const valueAlias = item?.componentProps?.optionsAlias?.valueField
return (
<ElOption
label={labelAlias ? option[labelAlias] : option['label']}
value={valueAlias ? option[valueAlias] : option['value']}
>
<ElOption label={option[labelAlias || 'label']} value={option[valueAlias || 'value']}>
{{
default: () =>
// option 插槽名规则,{field}-option
item.optionsSlot ? getSlot(slots, `${item.field}-option`, { item: option }) : undefined
item?.componentProps?.optionsSlot
? getSlot(slots, `${item.field}-option`, { item: option })
: undefined
}}
</ElOption>
)