wip(VForm): VForm component development

This commit is contained in:
陈凯龙 2021-12-25 10:51:01 +08:00
parent 497b8fc5b4
commit d16a5aa75e
6 changed files with 126 additions and 50 deletions

View File

@ -316,6 +316,22 @@ const options3: FormOptions[] = [
} }
] ]
function generateData() {
const data: {
value: number
desc: string
disabled: boolean
}[] = []
for (let i = 1; i <= 15; i++) {
data.push({
value: i,
desc: `Option ${i}`,
disabled: i % 4 === 0
})
}
return data
}
const schema = reactive<VFormSchema[]>([ const schema = reactive<VFormSchema[]>([
{ {
field: 'field1', field: 'field1',
@ -618,6 +634,82 @@ const schema = reactive<VFormSchema[]>([
voidIcon: markRaw(ChatRound), voidIcon: markRaw(ChatRound),
icons: [markRaw(ChatRound), markRaw(ChatLineRound), markRaw(ChatDotRound)] icons: [markRaw(ChatRound), markRaw(ChatLineRound), markRaw(ChatDotRound)]
} }
},
{
field: 'field32',
label: t('formDemo.colorPicker'),
component: 'Divider'
},
{
field: 'field33',
label: t('formDemo.default'),
component: 'ColorPicker'
},
{
field: 'field34',
label: t('formDemo.transfer'),
component: 'Divider'
},
{
field: 'field35',
label: t('formDemo.default'),
component: 'Transfer',
componentProps: {
props: {
key: 'value',
label: 'desc',
disabled: 'disabled'
},
data: generateData()
},
value: [],
colProps: {
xl: 12
}
},
{
field: 'field36',
label: t('formDemo.slot'),
component: 'Transfer',
componentProps: {
props: {
key: 'value',
label: 'desc',
disabled: 'disabled'
},
leftDefaultChecked: [2, 3],
rightDefaultChecked: [1],
data: generateData(),
slots: {
default: true
}
},
value: [1],
colProps: {
xl: 12
}
},
{
field: 'field37',
label: `${t('formDemo.render')}`,
component: 'Transfer',
componentProps: {
props: {
key: 'value',
label: 'desc',
disabled: 'disabled'
},
leftDefaultChecked: [2, 3],
rightDefaultChecked: [1],
data: generateData(),
renderContent: (h: Fn, option: Recordable) => {
return h('span', null, `${option.value} - ${option.desc}`)
}
},
value: [1],
colProps: {
xl: 12
}
} }
]) ])
@ -679,6 +771,10 @@ setTimeout(() => {
<span>{{ data.label }}</span> <span>{{ data.label }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span> <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template> </template>
<template #field36-default="{ option }">
<span>{{ option.value }} - {{ option.desc }}</span>
</template>
</VFrom> </VFrom>
</ElConfigProvider> </ElConfigProvider>
</template> </template>

View File

@ -12,7 +12,6 @@ import {
setModel setModel
} from './helper' } from './helper'
import { useRenderSelect } from './components/useRenderSelect' import { useRenderSelect } from './components/useRenderSelect'
import { useRenderCascader } from './components/useRenderCascader'
export default defineComponent({ export default defineComponent({
name: 'VForm', name: 'VForm',
@ -90,7 +89,13 @@ export default defineComponent({
// formItem // formItem
function renderFormItem(item: VFormSchema) { function renderFormItem(item: VFormSchema) {
// options // options
const notRenderOptions = ['SelectV2', 'Cascader'] const notRenderOptions = ['SelectV2', 'Cascader', 'Transfer']
const slotsMap: Recordable = {
...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
}
if (item?.component !== 'SelectV2' && item.options) {
slotsMap.default = () => renderOptions(item)
}
return ( return (
<ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label}> <ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label}>
{() => { {() => {
@ -99,20 +104,12 @@ export default defineComponent({
<Com <Com
vModel={formModel[item.field]} vModel={formModel[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))} {...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item.componentProps)} {...setComponentProps(item)}
options={ {...(notRenderOptions.includes(item?.component as string) && item.options
notRenderOptions.includes(item?.component as string) ? { options: item.options || [] }
? item.options || [] : {})}
: undefined
}
> >
{{ {{ ...slotsMap }}
default: (data: Recordable) =>
item.options && item?.component !== 'SelectV2'
? renderOptions(item, data)
: undefined,
...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
}}
</Com> </Com>
) )
}} }}
@ -121,14 +118,11 @@ export default defineComponent({
} }
// options // options
function renderOptions(item: VFormSchema, data: Recordable) { function renderOptions(item: VFormSchema) {
switch (item.component) { switch (item.component) {
case 'Select': case 'Select':
const { renderSelectOptions } = useRenderSelect(slots) const { renderSelectOptions } = useRenderSelect(slots)
return renderSelectOptions(item) return renderSelectOptions(item)
case 'Cascader':
const { useRenderCascaderOptions } = useRenderCascader(slots)
return useRenderCascaderOptions(item, data)
default: default:
break break
} }

View File

@ -1,23 +0,0 @@
import { Slots } from 'vue'
import { getSlot } from '@/utils/tsxHelper'
// 这个可能是element-plus的BUG需要这么处理才能渲染出来。
export function useRenderCascader(slots: Slots) {
function useRenderCascaderOptions(item: VFormSchema, data: Recordable) {
return (
<span>
{{
default: () => {
return item?.componentProps?.slots?.default
? getSlot(slots, `${item.field}-default`, data)
: data?.data[item?.optionsField?.labelField || 'label']
}
}}
</span>
)
}
return {
useRenderCascaderOptions
}
}

View File

@ -71,13 +71,16 @@ export function setGridProp(col: ColProps = {}): ColProps {
/** /**
* *
* @param props * @param item
* @returns clearable * @returns clearable
*/ */
export function setComponentProps(props: Recordable = {}): Recordable { export function setComponentProps(item: VFormSchema): Recordable {
const componentProps: Recordable = { const notNeedClearable = ['ColorPicker']
const componentProps: Recordable = notNeedClearable.includes(item.component as string)
? { ...item.componentProps }
: {
clearable: true, clearable: true,
...props ...item.componentProps
} }
// 需要删除额外的属性 // 需要删除额外的属性
delete componentProps?.slots delete componentProps?.slots

View File

@ -20,6 +20,9 @@ export default {
selectV2: 'SelectV2', selectV2: 'SelectV2',
cascader: 'Cascader', cascader: 'Cascader',
switch: 'Switch', switch: 'Switch',
rate: 'Rate' rate: 'Rate',
colorPicker: 'ColorPicker',
transfer: 'Transfer',
render: 'Render'
} }
} }

View File

@ -20,6 +20,9 @@ export default {
selectV2: '虚拟列表选择器', selectV2: '虚拟列表选择器',
cascader: '级联选择器', cascader: '级联选择器',
switch: '开关', switch: '开关',
rate: '评分' rate: '评分',
colorPicker: '颜色选择器',
transfer: '穿梭框',
render: '渲染器'
} }
} }