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

@ -6128,8 +6128,8 @@ packages:
vue-i18n: vue-i18n:
optional: true optional: true
dependencies: dependencies:
'@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.23 '@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.25
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23 '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
jsonc-eslint-parser: registry.npmmirror.com/jsonc-eslint-parser/1.4.1 jsonc-eslint-parser: registry.npmmirror.com/jsonc-eslint-parser/1.4.1
source-map: registry.nlark.com/source-map/0.6.1 source-map: registry.nlark.com/source-map/0.6.1
vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.24 vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.24
@ -6185,18 +6185,18 @@ packages:
source-map: registry.nlark.com/source-map/0.6.1 source-map: registry.nlark.com/source-map/0.6.1
dev: false dev: false
registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.23: registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.25:
resolution: resolution:
{ {
integrity: sha512-qmGN8k5yGGdZ5St8yg8U4Tg2K9Sc6h3BhWCdJKAqQVs5jnfZG+nMtsLVgnJUWkDvhjzyg7/rEOhHm2uJcu4vjw==, integrity: sha512-/YMG6LmQLvD8uHCJvWLaK0t8exYbek3ya4BZZ99AcM5+JC/JRdLIK8WiVJnGpfrvleQArxvHed4GokS+oWZ5rQ==,
registry: https://registry.npm.taobao.org/, registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.23.tgz tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.25.tgz
} }
name: '@intlify/message-compiler' name: '@intlify/message-compiler'
version: 9.2.0-beta.23 version: 9.2.0-beta.25
engines: { node: '>= 12' } engines: { node: '>= 12' }
dependencies: dependencies:
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23 '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
source-map: registry.nlark.com/source-map/0.6.1 source-map: registry.nlark.com/source-map/0.6.1
dev: true dev: true
@ -6240,15 +6240,15 @@ packages:
engines: { node: '>= 10' } engines: { node: '>= 10' }
dev: false dev: false
registry.npmmirror.com/@intlify/shared/9.2.0-beta.23: registry.npmmirror.com/@intlify/shared/9.2.0-beta.25:
resolution: resolution:
{ {
integrity: sha512-3aELL2KTp1MWKGm2gIUKSagthgKzcK5hpQEFzOwkJ1SAthpTXR7BHeWGEaD+Lj+Pbiz3U8cspvp8s2lFWVbYxg==, integrity: sha512-I2L05aWh0azr5KwQjLV7gMTN0SrdglgMAfpJniT53Pvvc8l+OTs8IEhdPCQwsbgOravpWt14O7m3deOzw3ln6w==,
registry: https://registry.npm.taobao.org/, registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.23.tgz tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.25.tgz
} }
name: '@intlify/shared' name: '@intlify/shared'
version: 9.2.0-beta.23 version: 9.2.0-beta.25
engines: { node: '>= 12' } engines: { node: '>= 12' }
dev: true dev: true
@ -6274,7 +6274,7 @@ packages:
optional: true optional: true
dependencies: dependencies:
'@intlify/bundle-utils': registry.npmmirror.com/@intlify/bundle-utils/2.2.0_vue-i18n@9.1.9 '@intlify/bundle-utils': registry.npmmirror.com/@intlify/bundle-utils/2.2.0_vue-i18n@9.1.9
'@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23 '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
'@rollup/pluginutils': registry.nlark.com/@rollup/pluginutils/4.1.1 '@rollup/pluginutils': registry.nlark.com/@rollup/pluginutils/4.1.1
debug: registry.npmmirror.com/debug/4.3.3 debug: registry.npmmirror.com/debug/4.3.3
fast-glob: registry.nlark.com/fast-glob/3.2.7 fast-glob: registry.nlark.com/fast-glob/3.2.7
@ -8693,13 +8693,12 @@ packages:
registry.npmmirror.com/lodash/4.17.21: registry.npmmirror.com/lodash/4.17.21:
resolution: resolution:
{ {
integrity: sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=, integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==,
registry: https://registry.npm.taobao.org/, registry: https://registry.npm.taobao.org/,
tarball: https://registry.npmmirror.com/lodash/download/lodash-4.17.21.tgz tarball: https://registry.npmmirror.com/lodash/download/lodash-4.17.21.tgz
} }
name: lodash name: lodash
version: 4.17.21 version: 4.17.21
dev: false
registry.npmmirror.com/log-update/4.0.0: registry.npmmirror.com/log-update/4.0.0:
resolution: resolution:
@ -10291,7 +10290,7 @@ packages:
version: 0.3.2 version: 0.3.2
dependencies: dependencies:
eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/1.3.0 eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/1.3.0
lodash: registry.nlark.com/lodash/4.17.21 lodash: registry.npmmirror.com/lodash/4.17.21
yaml: registry.npmmirror.com/yaml/1.10.2 yaml: registry.npmmirror.com/yaml/1.10.2
dev: true dev: true

View File

@ -45,13 +45,13 @@ onMounted(() => {
}) })
const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
const options = ref<FormOptions[]>( const options = ref<ComponentOptions[]>(
Array.from({ length: 1000 }).map((_, idx) => ({ Array.from({ length: 1000 }).map((_, idx) => ({
value: `Option ${idx + 1}`, value: `Option ${idx + 1}`,
label: `${initials[idx % 10]}${idx}` label: `${initials[idx % 10]}${idx}`
})) }))
) )
const options2 = ref<FormOptions[]>( const options2 = ref<ComponentOptions[]>(
Array.from({ length: 10 }).map((_, idx) => { Array.from({ length: 10 }).map((_, idx) => {
const label = idx + 1 const label = idx + 1
return { return {
@ -65,7 +65,7 @@ const options2 = ref<FormOptions[]>(
}) })
) )
const options3: FormOptions[] = [ const options3: ComponentOptions[] = [
{ {
value: 'guide', value: 'guide',
label: 'Guide', label: 'Guide',
@ -332,6 +332,20 @@ function generateData() {
return data return data
} }
const holidays = [
'2021-10-01',
'2021-10-02',
'2021-10-03',
'2021-10-04',
'2021-10-05',
'2021-10-06',
'2021-10-07'
]
function isHoliday({ dayjs }) {
return holidays.includes(dayjs.format('YYYY-MM-DD'))
}
const schema = reactive<VFormSchema[]>([ const schema = reactive<VFormSchema[]>([
{ {
field: 'field1', field: 'field1',
@ -438,99 +452,107 @@ const schema = reactive<VFormSchema[]>([
field: 'field14', field: 'field14',
label: t('formDemo.default'), label: t('formDemo.default'),
component: 'Select', component: 'Select',
options: [ componentProps: {
{ options: [
label: '选项1', {
value: '1' label: 'option1',
}, value: '1'
{ },
label: '选项2', {
value: '2' label: 'option2',
} value: '2'
] }
]
}
}, },
{ {
field: 'field15', field: 'field15',
label: t('formDemo.slot'), label: t('formDemo.slot'),
component: 'Select', component: 'Select',
options: [ componentProps: {
{ options: [
label: '选项1', {
value: '1' label: 'option1',
}, value: '1'
{ },
label: '选项2', {
value: '2' label: 'option2',
} value: '2'
], }
optionsSlot: true ],
optionsSlot: true
}
}, },
{ {
field: 'field16', field: 'field16',
label: t('formDemo.group'), label: t('formDemo.selectGroup'),
component: 'Select', component: 'Select',
options: [ componentProps: {
{ options: [
label: '选项1', {
options: [ label: 'option1',
{ options: [
label: '选项1-1', {
value: '1-1' label: 'option1-1',
}, value: '1-1'
{ },
label: '选项1-2', {
value: '1-2' label: 'option1-2',
} value: '1-2'
] }
}, ]
{ },
label: '选项2', {
options: [ label: 'option2',
{ options: [
label: '选项2-1', {
value: '2-1' label: 'option2-1',
}, value: '2-1'
{ },
label: '选项2-2', {
value: '2-2' label: 'option2-2',
} value: '2-2'
] }
} ]
] }
]
}
}, },
{ {
field: 'field17', field: 'field17',
label: `${t('formDemo.group')}${t('formDemo.slot')}`, label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
component: 'Select', component: 'Select',
options: [ componentProps: {
{ options: [
label: '选项1', {
options: [ label: 'option1',
{ options: [
label: '选项1-1', {
value: '1-1' label: 'option1-1',
}, value: '1-1'
{ },
label: '选项1-2', {
value: '1-2' label: 'option1-2',
} value: '1-2'
] }
}, ]
{ },
label: '选项2', {
options: [ label: 'option2',
{ options: [
label: '选项2-1', {
value: '2-1' label: 'option2-1',
}, value: '2-1'
{ },
label: '选项2-2', {
value: '2-2' label: 'option2-2',
} value: '2-2'
] }
} ]
], }
optionsSlot: true ],
optionsSlot: true
}
}, },
{ {
field: 'field18', field: 'field18',
@ -541,14 +563,16 @@ const schema = reactive<VFormSchema[]>([
field: 'field19', field: 'field19',
label: t('formDemo.default'), label: t('formDemo.default'),
component: 'SelectV2', component: 'SelectV2',
options: options.value componentProps: {
options: options.value
}
}, },
{ {
field: 'field20', field: 'field20',
label: t('formDemo.slot'), label: t('formDemo.slot'),
component: 'SelectV2', component: 'SelectV2',
options: options.value,
componentProps: { componentProps: {
options: options.value,
slots: { slots: {
default: true default: true
} }
@ -556,16 +580,18 @@ const schema = reactive<VFormSchema[]>([
}, },
{ {
field: 'field21', field: 'field21',
label: t('formDemo.group'), label: t('formDemo.selectGroup'),
component: 'SelectV2', component: 'SelectV2',
options: options2.value componentProps: {
options: options2.value
}
}, },
{ {
field: 'field22', field: 'field22',
label: `${t('formDemo.group')}${t('formDemo.slot')}`, label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
component: 'SelectV2', component: 'SelectV2',
options: options2.value,
componentProps: { componentProps: {
options: options2.value,
slots: { slots: {
default: true default: true
} }
@ -580,14 +606,16 @@ const schema = reactive<VFormSchema[]>([
field: 'field24', field: 'field24',
label: t('formDemo.default'), label: t('formDemo.default'),
component: 'Cascader', component: 'Cascader',
options: options3 componentProps: {
options: options3
}
}, },
{ {
field: 'field25', field: 'field25',
label: t('formDemo.slot'), label: t('formDemo.slot'),
component: 'Cascader', component: 'Cascader',
options: options3,
componentProps: { componentProps: {
options: options3,
slots: { slots: {
default: true default: true
} }
@ -710,15 +738,286 @@ const schema = reactive<VFormSchema[]>([
colProps: { colProps: {
xl: 12 xl: 12
} }
},
{
field: 'field38',
label: t('formDemo.radio'),
component: 'Divider'
},
{
field: 'field39',
label: t('formDemo.default'),
component: 'Radio',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field40',
label: t('formDemo.button'),
component: 'RadioButton',
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
}
]
}
},
{
field: 'field41',
label: t('formDemo.checkbox'),
component: 'Divider'
},
{
field: 'field42',
label: t('formDemo.default'),
component: 'Checkbox',
value: [],
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '23'
}
]
}
},
{
field: 'field43',
label: t('formDemo.button'),
component: 'CheckboxButton',
value: [],
componentProps: {
options: [
{
label: 'option-1',
value: '1'
},
{
label: 'option-2',
value: '2'
},
{
label: 'option-3',
value: '23'
}
]
}
},
{
field: 'field44',
component: 'Divider',
label: t('formDemo.slider')
},
{
field: 'field45',
component: 'Slider',
label: t('formDemo.default'),
value: 0
},
{
field: 'field46',
component: 'Divider',
label: t('formDemo.datePicker')
},
{
field: 'field47',
component: 'DatePicker',
label: t('formDemo.default'),
componentProps: {
type: 'date'
}
},
{
field: 'field48',
component: 'DatePicker',
label: t('formDemo.shortcuts'),
componentProps: {
type: 'date',
disabledDate: (time: Date) => {
return time.getTime() > Date.now()
},
shortcuts: [
{
text: t('formDemo.today'),
value: new Date()
},
{
text: t('formDemo.yesterday'),
value: () => {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24)
return date
}
},
{
text: t('formDemo.aWeekAgo'),
value: () => {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
return date
}
}
]
}
},
{
field: 'field49',
component: 'DatePicker',
label: t('formDemo.week'),
componentProps: {
type: 'week',
format: `[${t('formDemo.week')}] ww`
}
},
{
field: 'field50',
component: 'DatePicker',
label: t('formDemo.year'),
componentProps: {
type: 'year'
}
},
{
field: 'field51',
component: 'DatePicker',
label: t('formDemo.month'),
componentProps: {
type: 'month'
}
},
{
field: 'field52',
component: 'DatePicker',
label: t('formDemo.dates'),
componentProps: {
type: 'dates'
}
},
{
field: 'field53',
component: 'DatePicker',
label: t('formDemo.daterange'),
componentProps: {
type: 'daterange'
}
},
{
field: 'field54',
component: 'DatePicker',
label: t('formDemo.monthrange'),
componentProps: {
type: 'monthrange'
}
},
{
field: 'field55',
component: 'DatePicker',
label: t('formDemo.slot'),
componentProps: {
type: 'date',
format: 'YYYY/MM/DD',
valueFormat: 'YYYY-MM-DD',
slots: {
default: true
}
}
},
{
field: 'field56',
component: 'Divider',
label: t('formDemo.dateTimePicker')
},
{
field: 'field57',
component: 'DatePicker',
label: t('formDemo.default'),
componentProps: {
type: 'datetime'
}
},
{
field: 'field58',
component: 'DatePicker',
label: t('formDemo.shortcuts'),
componentProps: {
type: 'datetime',
shortcuts: [
{
text: t('formDemo.today'),
value: new Date()
},
{
text: t('formDemo.yesterday'),
value: () => {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24)
return date
}
},
{
text: t('formDemo.aWeekAgo'),
value: () => {
const date = new Date()
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
return date
}
}
]
}
},
{
field: 'field59',
component: 'DatePicker',
label: t('formDemo.dateTimerange'),
componentProps: {
type: 'datetimerange'
}
},
{
field: 'field60',
component: 'Divider',
label: t('formDemo.timePicker')
},
{
field: 'field61',
component: 'TimePicker',
label: t('formDemo.default')
},
{
field: 'field62',
component: 'Divider',
label: t('formDemo.timeSelect')
},
{
field: 'field63',
component: 'TimeSelect',
label: t('formDemo.default')
} }
]) ])
setTimeout(() => {
if (schema[2].componentProps) {
schema[2].componentProps.placeholder = 'test'
console.log(schema[2])
}
}, 3000)
</script> </script>
<template> <template>
@ -775,6 +1074,51 @@ setTimeout(() => {
<template #field36-default="{ option }"> <template #field36-default="{ option }">
<span>{{ option.value }} - {{ option.desc }}</span> <span>{{ option.value }} - {{ option.desc }}</span>
</template> </template>
<template #field55-default="cell">
<div class="cell" :class="{ current: cell.isCurrent }">
<span class="text">{{ cell.text }}</span>
<span v-if="isHoliday(cell)" class="holiday"></span>
</div>
</template>
</VFrom> </VFrom>
</ElConfigProvider> </ElConfigProvider>
</template> </template>
<style lang="less" scoped>
.cell {
height: 30px;
padding: 3px 0;
box-sizing: border-box;
.text {
position: absolute;
left: 50%;
display: block;
width: 24px;
height: 24px;
margin: 0 auto;
line-height: 24px;
border-radius: 50%;
transform: translateX(-50%);
}
&.current {
.text {
color: #fff;
background: purple;
}
}
.holiday {
position: absolute;
bottom: 0px;
left: 50%;
width: 6px;
height: 6px;
background: red;
border-radius: 50%;
transform: translateX(-50%);
}
}
</style>

View File

@ -12,6 +12,8 @@ import {
setModel setModel
} from './helper' } from './helper'
import { useRenderSelect } from './components/useRenderSelect' import { useRenderSelect } from './components/useRenderSelect'
import { useRenderRadio } from './components/useRenderRadio'
import { useRenderChcekbox } from './components/useRenderChcekbox'
export default defineComponent({ export default defineComponent({
name: 'VForm', name: 'VForm',
@ -93,7 +95,11 @@ export default defineComponent({
const slotsMap: Recordable = { const slotsMap: Recordable = {
...setItemComponentSlots(slots, item?.componentProps?.slots, item.field) ...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) slotsMap.default = () => renderOptions(item)
} }
return ( return (
@ -105,8 +111,9 @@ export default defineComponent({
vModel={formModel[item.field]} vModel={formModel[item.field]}
{...(autoSetPlaceholder && setTextPlaceholder(item))} {...(autoSetPlaceholder && setTextPlaceholder(item))}
{...setComponentProps(item)} {...setComponentProps(item)}
{...(notRenderOptions.includes(item?.component as string) && item.options {...(notRenderOptions.includes(item?.component as string) &&
? { options: item.options || [] } item?.componentProps?.options
? { options: item?.componentProps?.options || [] }
: {})} : {})}
> >
{{ ...slotsMap }} {{ ...slotsMap }}
@ -123,6 +130,14 @@ export default defineComponent({
case 'Select': case 'Select':
const { renderSelectOptions } = useRenderSelect(slots) const { renderSelectOptions } = useRenderSelect(slots)
return renderSelectOptions(item) return renderSelectOptions(item)
case 'Radio':
case 'RadioButton':
const { renderRadioOptions } = useRenderRadio()
return renderRadioOptions(item)
case 'Checkbox':
case 'CheckboxButton':
const { renderChcekboxOptions } = useRenderChcekbox()
return renderChcekboxOptions(item)
default: default:
break break
} }
@ -142,7 +157,7 @@ export default defineComponent({
} }
return () => ( return () => (
<ElForm ref={formRef} {...getFormBindValue()} model={formModel}> <ElForm ref={formRef} {...getFormBindValue()} model={formModel} class="v-form">
{{ {{
// //
default: () => (isCustom ? getSlot(slots, 'default') : renderWrap()) default: () => (isCustom ? getSlot(slots, 'default') : renderWrap())

View File

@ -22,6 +22,7 @@ import {
const componentMap: Recordable<Component, ComponentName> = { const componentMap: Recordable<Component, ComponentName> = {
Radio: ElRadioGroup, Radio: ElRadioGroup,
Checkbox: ElCheckboxGroup, Checkbox: ElCheckboxGroup,
CheckboxButton: ElCheckboxGroup,
Input: ElInput, Input: ElInput,
Autocomplete: ElAutocomplete, Autocomplete: ElAutocomplete,
InputNumber: ElInputNumber, InputNumber: ElInputNumber,
@ -36,7 +37,8 @@ const componentMap: Recordable<Component, ComponentName> = {
Transfer: ElTransfer, Transfer: ElTransfer,
Divider: ElDivider, Divider: ElDivider,
TimeSelect: ElTimeSelect, TimeSelect: ElTimeSelect,
SelectV2: ElSelectV2 SelectV2: ElSelectV2,
RadioButton: ElRadioGroup
} }
export { componentMap } 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 // 渲染 select options
function renderSelectOptions(item: VFormSchema) { function renderSelectOptions(item: VFormSchema) {
// 如果有别名,就取别名 // 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField const labelAlias = item?.componentProps?.optionsAlias?.labelField
return item.options?.map((option) => { return item?.componentProps?.options?.map((option) => {
if (option?.options?.length) { if (option?.options?.length) {
return ( return (
<ElOptionGroup label={labelAlias ? option[labelAlias] : option['label']}> <ElOptionGroup label={option[labelAlias || 'label']}>
{() => { {() => {
return option?.options?.map((v) => { return option?.options?.map((v) => {
return renderSelectOptionItem(item, v) return renderSelectOptionItem(item, v)
@ -25,19 +25,18 @@ export function useRenderSelect(slots: Slots) {
} }
// 渲染 select option item // 渲染 select option item
function renderSelectOptionItem(item: VFormSchema, option: FormOptions) { function renderSelectOptionItem(item: VFormSchema, option: ComponentOptions) {
// 如果有别名,就取别名 // 如果有别名,就取别名
const labelAlias = item.optionsField?.labelField const labelAlias = item?.componentProps?.optionsAlias?.labelField
const valueAlias = item.optionsField?.valueField const valueAlias = item?.componentProps?.optionsAlias?.valueField
return ( return (
<ElOption <ElOption label={option[labelAlias || 'label']} value={option[valueAlias || 'value']}>
label={labelAlias ? option[labelAlias] : option['label']}
value={valueAlias ? option[valueAlias] : option['value']}
>
{{ {{
default: () => default: () =>
// option 插槽名规则,{field}-option // 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> </ElOption>
) )

View File

@ -16,13 +16,32 @@ export default {
position: 'Position', position: 'Position',
autocomplete: 'Autocomplete', autocomplete: 'Autocomplete',
select: 'Select', select: 'Select',
group: 'Select Group', selectGroup: 'Select Group',
selectV2: 'SelectV2', selectV2: 'SelectV2',
cascader: 'Cascader', cascader: 'Cascader',
switch: 'Switch', switch: 'Switch',
rate: 'Rate', rate: 'Rate',
colorPicker: 'ColorPicker', colorPicker: 'Color Picker',
transfer: 'Transfer', transfer: 'Transfer',
render: 'Render' render: 'Render',
radio: 'Radio',
button: 'Button',
checkbox: 'Checkbox',
slider: 'Slider',
datePicker: 'Date Picker',
shortcuts: 'Shortcuts',
today: 'Today',
yesterday: 'Yesterday',
aWeekAgo: 'A week ago',
week: 'Week',
year: 'Year',
month: 'Month',
dates: 'Dates',
daterange: 'Date Range',
monthrange: 'Month Range',
dateTimePicker: 'DateTimePicker',
dateTimerange: 'Datetime Range',
timePicker: 'Time Picker',
timeSelect: 'Time Select'
} }
} }

View File

@ -16,13 +16,32 @@ export default {
position: '位置', position: '位置',
autocomplete: '自动补全', autocomplete: '自动补全',
select: '选择器', select: '选择器',
group: '选项分组', selectGroup: '选项分组',
selectV2: '虚拟列表选择器', selectV2: '虚拟列表选择器',
cascader: '级联选择器', cascader: '级联选择器',
switch: '开关', switch: '开关',
rate: '评分', rate: '评分',
colorPicker: '颜色选择器', colorPicker: '颜色选择器',
transfer: '穿梭框', transfer: '穿梭框',
render: '渲染器' render: '渲染器',
radio: '单选框',
button: '按钮',
checkbox: '多选框',
slider: '滑块',
datePicker: '日期选择器',
shortcuts: '快捷选项',
today: '今天',
yesterday: '昨天',
aWeekAgo: '一周前',
week: '周',
year: '年',
month: '月',
dates: '日期',
daterange: '日期范围',
monthrange: '月份范围',
dateTimePicker: '日期时间选择器',
dateTimerange: '日期时间范围',
timePicker: '时间选择器',
timeSelect: '时间选择'
} }
} }

View File

@ -5,7 +5,9 @@ declare global {
// BfForm types start // BfForm types start
declare type ComponentName = declare type ComponentName =
| 'Radio' | 'Radio'
| 'RadioButton'
| 'Checkbox' | 'Checkbox'
| 'CheckboxButton'
| 'Input' | 'Input'
| 'Autocomplete' | 'Autocomplete'
| 'InputNumber' | 'InputNumber'
@ -52,21 +54,26 @@ declare global {
style?: CSSProperties style?: CSSProperties
} }
declare type FormOptions = { declare type ComponentOptions = {
label?: string label?: string
value?: FormValueTypes value?: FormValueTypes
disabled?: boolean disabled?: boolean
key?: string | number key?: string | number
children?: FormOptions[] children?: ComponentOptions[]
options?: FormOptions[] options?: ComponentOptions[]
[key: string]: any } & Recordable
}
declare type FormOptionsAlias = { declare type ComponentOptionsAlias = {
labelField?: string labelField?: string
valueField?: string valueField?: string
} }
declare type ComponentProps = {
optionsAlias?: ComponentOptionsAlias
options?: ComponentOptions[]
optionsSlot?: boolean
} & Recordable
declare type VFormSchema = { declare type VFormSchema = {
// 唯一值 // 唯一值
field: string field: string
@ -75,23 +82,15 @@ declare global {
// col组件属性 // col组件属性
colProps?: ColProps colProps?: ColProps
// 表单组件属性slots对应的是表单组件的插槽规则${field}-xxx具体可以查看element-plus文档 // 表单组件属性slots对应的是表单组件的插槽规则${field}-xxx具体可以查看element-plus文档
componentProps?: { slots?: Recordable } & Recordable componentProps?: { slots?: Recordable } & ComponentProps
// formItem组件属性 // formItem组件属性
formItemProps?: FormItemProps formItemProps?: FormItemProps
// 渲染的组件 // 渲染的组件
component?: ComponentName component?: ComponentName
// 初始值 // 初始值
value?: FormValueTypes value?: FormValueTypes
// 下拉选项
options?: FormOptions[]
// 下拉选项别名
optionsField?: FormOptionsAlias
// 下拉选项插槽,规则:${field}-option
optionsSlot?: boolean
// 是否隐藏 // 是否隐藏
hidden?: boolean hidden?: boolean
// 表单组件插槽,规则:${field}
slot?: boolean
} }
// VForm types end // VForm types end