feat: improve element plus form component (#5072)
This commit is contained in:
parent
958c8b4f21
commit
305549e7f2
@ -15,12 +15,16 @@ import { $t } from '@vben/locales';
|
|||||||
import {
|
import {
|
||||||
ElButton,
|
ElButton,
|
||||||
ElCheckbox,
|
ElCheckbox,
|
||||||
|
ElCheckboxButton,
|
||||||
ElCheckboxGroup,
|
ElCheckboxGroup,
|
||||||
ElDatePicker,
|
ElDatePicker,
|
||||||
ElDivider,
|
ElDivider,
|
||||||
ElInput,
|
ElInput,
|
||||||
ElInputNumber,
|
ElInputNumber,
|
||||||
ElNotification,
|
ElNotification,
|
||||||
|
ElOption,
|
||||||
|
ElRadio,
|
||||||
|
ElRadioButton,
|
||||||
ElRadioGroup,
|
ElRadioGroup,
|
||||||
ElSelect,
|
ElSelect,
|
||||||
ElSelectV2,
|
ElSelectV2,
|
||||||
@ -79,7 +83,25 @@ async function initComponentAdapter() {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
Checkbox: ElCheckbox,
|
Checkbox: ElCheckbox,
|
||||||
CheckboxGroup: ElCheckboxGroup,
|
CheckboxGroup: (props, { attrs, slots }) => {
|
||||||
|
let defaultSlot;
|
||||||
|
if (Reflect.has(slots, 'default')) {
|
||||||
|
defaultSlot = slots.default;
|
||||||
|
} else {
|
||||||
|
const { options, isButton } = attrs;
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
defaultSlot = () =>
|
||||||
|
options.map((option) =>
|
||||||
|
h(isButton ? ElCheckboxButton : ElCheckbox, option),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return h(
|
||||||
|
ElCheckboxGroup,
|
||||||
|
{ ...props, ...attrs },
|
||||||
|
{ ...slots, default: defaultSlot },
|
||||||
|
);
|
||||||
|
},
|
||||||
// 自定义默认按钮
|
// 自定义默认按钮
|
||||||
DefaultButton: (props, { attrs, slots }) => {
|
DefaultButton: (props, { attrs, slots }) => {
|
||||||
return h(ElButton, { ...props, attrs, type: 'info' }, slots);
|
return h(ElButton, { ...props, attrs, type: 'info' }, slots);
|
||||||
@ -104,8 +126,42 @@ async function initComponentAdapter() {
|
|||||||
},
|
},
|
||||||
Input: withDefaultPlaceholder(ElInput, 'input'),
|
Input: withDefaultPlaceholder(ElInput, 'input'),
|
||||||
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
|
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
|
||||||
RadioGroup: ElRadioGroup,
|
RadioGroup: (props, { attrs, slots }) => {
|
||||||
Select: withDefaultPlaceholder(ElSelect, 'select'),
|
let defaultSlot;
|
||||||
|
if (Reflect.has(slots, 'default')) {
|
||||||
|
defaultSlot = slots.default;
|
||||||
|
} else {
|
||||||
|
const { options } = attrs;
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
defaultSlot = () =>
|
||||||
|
options.map((option) =>
|
||||||
|
h(attrs.isButton ? ElRadioButton : ElRadio, option),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return h(
|
||||||
|
ElRadioGroup,
|
||||||
|
{ ...props, ...attrs },
|
||||||
|
{ ...slots, default: defaultSlot },
|
||||||
|
);
|
||||||
|
},
|
||||||
|
Select: (props, { attrs, slots }) => {
|
||||||
|
let defaultSlot;
|
||||||
|
if (Reflect.has(slots, 'default')) {
|
||||||
|
defaultSlot = slots.default;
|
||||||
|
} else {
|
||||||
|
const { options } = attrs;
|
||||||
|
if (Array.isArray(options)) {
|
||||||
|
defaultSlot = () => options.map((option) => h(ElOption, option));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const placeholder = props?.placeholder || $t(`ui.placeholder.select`);
|
||||||
|
return h(
|
||||||
|
ElSelect,
|
||||||
|
{ ...props, ...attrs, placeholder },
|
||||||
|
{ ...slots, default: defaultSlot },
|
||||||
|
);
|
||||||
|
},
|
||||||
Space: ElSpace,
|
Space: ElSpace,
|
||||||
Switch: ElSwitch,
|
Switch: ElSwitch,
|
||||||
TimePicker: (props, { attrs, slots }) => {
|
TimePicker: (props, { attrs, slots }) => {
|
||||||
|
@ -12,6 +12,7 @@ setupVbenForm<ComponentType>({
|
|||||||
config: {
|
config: {
|
||||||
modelPropNameMap: {
|
modelPropNameMap: {
|
||||||
Upload: 'fileList',
|
Upload: 'fileList',
|
||||||
|
CheckboxGroup: 'model-value',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
defineRules: {
|
defineRules: {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"title": "Demos",
|
"title": "Demos",
|
||||||
"elementPlus": "Element Plus",
|
"elementPlus": "Element Plus",
|
||||||
|
"form": "Form",
|
||||||
"vben": {
|
"vben": {
|
||||||
"title": "Project",
|
"title": "Project",
|
||||||
"about": "About",
|
"about": "About",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"title": "演示",
|
"title": "演示",
|
||||||
"elementPlus": "Element Plus",
|
"elementPlus": "Element Plus",
|
||||||
|
"form": "表单演示",
|
||||||
"vben": {
|
"vben": {
|
||||||
"title": "项目",
|
"title": "项目",
|
||||||
"about": "关于",
|
"about": "关于",
|
||||||
|
@ -23,6 +23,14 @@ const routes: RouteRecordRaw[] = [
|
|||||||
path: '/demos/element',
|
path: '/demos/element',
|
||||||
component: () => import('#/views/demos/element/index.vue'),
|
component: () => import('#/views/demos/element/index.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
meta: {
|
||||||
|
title: $t('demos.form'),
|
||||||
|
},
|
||||||
|
name: 'BasicForm',
|
||||||
|
path: '/demos/form',
|
||||||
|
component: () => import('#/views/demos/form/basic.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
143
apps/web-ele/src/views/demos/form/basic.vue
Normal file
143
apps/web-ele/src/views/demos/form/basic.vue
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { h } from 'vue';
|
||||||
|
|
||||||
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
|
import { ElButton, ElCard, ElCheckbox, ElMessage } from 'element-plus';
|
||||||
|
|
||||||
|
import { useVbenForm } from '#/adapter/form';
|
||||||
|
|
||||||
|
const [Form, formApi] = useVbenForm({
|
||||||
|
commonConfig: {
|
||||||
|
// 所有表单项
|
||||||
|
componentProps: {
|
||||||
|
class: 'w-full',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
layout: 'horizontal',
|
||||||
|
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||||
|
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
|
||||||
|
handleSubmit: (values) => {
|
||||||
|
ElMessage.success(`表单数据:${JSON.stringify(values)}`);
|
||||||
|
},
|
||||||
|
schema: [
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'string',
|
||||||
|
label: 'String',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'InputNumber',
|
||||||
|
fieldName: 'number',
|
||||||
|
label: 'Number',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'RadioGroup',
|
||||||
|
fieldName: 'radio',
|
||||||
|
label: 'Radio',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ value: 'A', label: 'A' },
|
||||||
|
{ value: 'B', label: 'B' },
|
||||||
|
{ value: 'C', label: 'C' },
|
||||||
|
{ value: 'D', label: 'D' },
|
||||||
|
{ value: 'E', label: 'E' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'RadioGroup',
|
||||||
|
fieldName: 'radioButton',
|
||||||
|
label: 'RadioButton',
|
||||||
|
componentProps: {
|
||||||
|
isButton: true,
|
||||||
|
options: ['A', 'B', 'C', 'D', 'E', 'F'].map((v) => ({
|
||||||
|
value: v,
|
||||||
|
label: `选项${v}`,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'CheckboxGroup',
|
||||||
|
fieldName: 'checkbox',
|
||||||
|
label: 'Checkbox',
|
||||||
|
componentProps: {
|
||||||
|
options: ['A', 'B', 'C'].map((v) => ({ value: v, label: `选项${v}` })),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'CheckboxGroup',
|
||||||
|
fieldName: 'checkbox1',
|
||||||
|
label: 'Checkbox1',
|
||||||
|
renderComponentContent: () => {
|
||||||
|
return {
|
||||||
|
default: () => {
|
||||||
|
return ['A', 'B', 'C', 'D'].map((v) =>
|
||||||
|
h(ElCheckbox, { label: v, value: v }),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'CheckboxGroup',
|
||||||
|
fieldName: 'checkbotton',
|
||||||
|
label: 'CheckBotton',
|
||||||
|
componentProps: {
|
||||||
|
isButton: true,
|
||||||
|
options: [
|
||||||
|
{ value: 'A', label: '选项A' },
|
||||||
|
{ value: 'B', label: '选项B' },
|
||||||
|
{ value: 'C', label: '选项C' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'DatePicker',
|
||||||
|
fieldName: 'date',
|
||||||
|
label: 'Date',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
fieldName: 'select',
|
||||||
|
label: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: [
|
||||||
|
{ value: 'A', label: '选项A' },
|
||||||
|
{ value: 'B', label: '选项B' },
|
||||||
|
{ value: 'C', label: '选项C' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
function setFormValues() {
|
||||||
|
formApi.setValues({
|
||||||
|
string: 'string',
|
||||||
|
number: 123,
|
||||||
|
radio: 'B',
|
||||||
|
radioButton: 'C',
|
||||||
|
checkbox: ['A', 'C'],
|
||||||
|
checkbotton: ['B', 'C'],
|
||||||
|
checkbox1: ['A', 'B'],
|
||||||
|
date: new Date(),
|
||||||
|
select: 'B',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<Page
|
||||||
|
description="我们重新包装了CheckboxGroup、RadioGroup、Select,可以通过options属性传入选项属性数组以自动生成选项"
|
||||||
|
title="表单演示"
|
||||||
|
>
|
||||||
|
<ElCard>
|
||||||
|
<template #header>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<span class="flex-auto">基础表单演示</span>
|
||||||
|
<ElButton type="primary" @click="setFormValues">设置表单值</ElButton>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<Form />
|
||||||
|
</ElCard>
|
||||||
|
</Page>
|
||||||
|
</template>
|
Loading…
Reference in New Issue
Block a user