wip(VForm): VForm component development
This commit is contained in:
parent
497b8fc5b4
commit
d16a5aa75e
96
src/App.vue
96
src/App.vue
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -71,14 +71,17 @@ 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']
|
||||||
clearable: true,
|
const componentProps: Recordable = notNeedClearable.includes(item.component as string)
|
||||||
...props
|
? { ...item.componentProps }
|
||||||
}
|
: {
|
||||||
|
clearable: true,
|
||||||
|
...item.componentProps
|
||||||
|
}
|
||||||
// 需要删除额外的属性
|
// 需要删除额外的属性
|
||||||
delete componentProps?.slots
|
delete componentProps?.slots
|
||||||
return componentProps
|
return componentProps
|
||||||
|
|
|
@ -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'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@ export default {
|
||||||
selectV2: '虚拟列表选择器',
|
selectV2: '虚拟列表选择器',
|
||||||
cascader: '级联选择器',
|
cascader: '级联选择器',
|
||||||
switch: '开关',
|
switch: '开关',
|
||||||
rate: '评分'
|
rate: '评分',
|
||||||
|
colorPicker: '颜色选择器',
|
||||||
|
transfer: '穿梭框',
|
||||||
|
render: '渲染器'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue