wip(VForm): VForm component development

This commit is contained in:
陈凯龙
2021-12-17 15:10:39 +08:00
parent 69909e2832
commit d9d64f3931
6 changed files with 144 additions and 52 deletions

View File

@@ -1,10 +1,11 @@
<script lang="tsx">
import { PropType, defineComponent, ref, computed, unref } from 'vue'
import { ElForm, ElFormItem, ElRow, ElCol, ElOption, ElOptionGroup } from 'element-plus'
import { ElForm, ElFormItem, ElRow, ElCol } from 'element-plus'
import { componentMap } from './componentMap'
import { propTypes } from '@/utils/propTypes'
import { getSlot } from '@/utils/tsxHelper'
import { setTextPlaceholder, setGridProp, setComponentProps, setItemComponentSlots } from './helper'
import { useRenderSelect } from './components/useRenderSelect'
export default defineComponent({
name: 'VForm',
@@ -74,9 +75,12 @@ export default defineComponent({
<Com
{...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item.componentProps)}
// 单独给SelectV2做判断
options={item.component === 'SelectV2' ? item.options || [] : undefined}
>
{{
default: () => (item.options ? renderOptions(item) : null),
default: () =>
item.options && item.component !== 'SelectV2' ? renderOptions(item) : undefined,
...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
}}
</Com>
@@ -90,52 +94,13 @@ export default defineComponent({
function renderOptions(item: VFormSchema) {
switch (item.component) {
case 'Select':
const { renderSelectOptions } = useRenderSelect(slots)
return renderSelectOptions(item)
default:
break
}
}
// 渲染 select options
function renderSelectOptions(item: VFormSchema) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
return item.options?.map((option) => {
if (option?.options?.length) {
return (
<ElOptionGroup label={labelAlias ? option[labelAlias] : option['label']}>
{() => {
return option?.options?.map((v) => {
return renderSelectOptionItem(item, v)
})
}}
</ElOptionGroup>
)
} else {
return renderSelectOptionItem(item, option)
}
})
}
// 渲染 select option item
function renderSelectOptionItem(item: VFormSchema, option: FormOptions) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
const valueAlias = item.optionsField?.valueField
return (
<ElOption
label={labelAlias ? option[labelAlias] : option['label']}
value={valueAlias ? option[valueAlias] : option['value']}
>
{{
default: () =>
// option 插槽名规则,{field}-option
item.optionsSlot ? getSlot(slots, `${item.field}-option`, option) : null
}}
</ElOption>
)
}
// 过滤传入Form组件的属性
function getFormBindValue() {
// 避免在标签上出现多余的属性

View File

@@ -0,0 +1,49 @@
import { ElOption, ElOptionGroup } from 'element-plus'
import { getSlot } from '@/utils/tsxHelper'
import { Slots } from 'vue'
export function useRenderSelect(slots: Slots) {
// 渲染 select options
function renderSelectOptions(item: VFormSchema) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
return item.options?.map((option) => {
if (option?.options?.length) {
return (
<ElOptionGroup label={labelAlias ? option[labelAlias] : option['label']}>
{() => {
return option?.options?.map((v) => {
return renderSelectOptionItem(item, v)
})
}}
</ElOptionGroup>
)
} else {
return renderSelectOptionItem(item, option)
}
})
}
// 渲染 select option item
function renderSelectOptionItem(item: VFormSchema, option: FormOptions) {
// 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField
const valueAlias = item.optionsField?.valueField
return (
<ElOption
label={labelAlias ? option[labelAlias] : option['label']}
value={valueAlias ? option[valueAlias] : option['value']}
>
{{
default: () =>
// option 插槽名规则,{field}-option
item.optionsSlot ? getSlot(slots, `${item.field}-option`, { item: option }) : undefined
}}
</ElOption>
)
}
return {
renderSelectOptions
}
}

View File

@@ -117,3 +117,5 @@ export function setItemComponentSlots(
}
return slotObj
}
export function setModel() {}