Skip to content

Commit

Permalink
feat: improve element plus form component (#5072)
Browse files Browse the repository at this point in the history
  • Loading branch information
mynetfan authored Dec 8, 2024
1 parent 958c8b4 commit 305549e
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 3 deletions.
62 changes: 59 additions & 3 deletions apps/web-ele/src/adapter/component/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ import { $t } from '@vben/locales';
import {
ElButton,
ElCheckbox,
ElCheckboxButton,
ElCheckboxGroup,
ElDatePicker,
ElDivider,
ElInput,
ElInputNumber,
ElNotification,
ElOption,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElSelect,
ElSelectV2,
Expand Down Expand Up @@ -79,7 +83,25 @@ async function initComponentAdapter() {
);
},
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 }) => {
return h(ElButton, { ...props, attrs, type: 'info' }, slots);
Expand All @@ -104,8 +126,42 @@ async function initComponentAdapter() {
},
Input: withDefaultPlaceholder(ElInput, 'input'),
InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
RadioGroup: ElRadioGroup,
Select: withDefaultPlaceholder(ElSelect, 'select'),
RadioGroup: (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(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,
Switch: ElSwitch,
TimePicker: (props, { attrs, slots }) => {
Expand Down
1 change: 1 addition & 0 deletions apps/web-ele/src/adapter/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ setupVbenForm<ComponentType>({
config: {
modelPropNameMap: {
Upload: 'fileList',
CheckboxGroup: 'model-value',
},
},
defineRules: {
Expand Down
1 change: 1 addition & 0 deletions apps/web-ele/src/locales/langs/en-US/demos.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"title": "Demos",
"elementPlus": "Element Plus",
"form": "Form",
"vben": {
"title": "Project",
"about": "About",
Expand Down
1 change: 1 addition & 0 deletions apps/web-ele/src/locales/langs/zh-CN/demos.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"title": "演示",
"elementPlus": "Element Plus",
"form": "表单演示",
"vben": {
"title": "项目",
"about": "关于",
Expand Down
8 changes: 8 additions & 0 deletions apps/web-ele/src/router/routes/modules/demos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ const routes: RouteRecordRaw[] = [
path: '/demos/element',
component: () => import('#/views/demos/element/index.vue'),
},
{
meta: {
title: $t('demos.form'),
},
name: 'BasicForm',
path: '/demos/form',
component: () => import('#/views/demos/form/basic.vue'),
},
],
},
];
Expand Down
143 changes: 143 additions & 0 deletions apps/web-ele/src/views/demos/form/basic.vue
Original file line number Diff line number Diff line change
@@ -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>

0 comments on commit 305549e

Please sign in to comment.