Skip to content

Commit 524b9ba

Browse files
anncwbjinmao88likui628
authored
feat: add VbenForm component (vbenjs#4352)
* feat: add form component * fix: build error * feat: add form adapter * feat: add some component * feat: add some component * feat: add example * feat: suppoer custom action button * chore: update * feat: add example * feat: add formModel,formDrawer demo * fix: build error * fix: typo * fix: ci error --------- Co-authored-by: jinmao <[email protected]> Co-authored-by: likui628 <[email protected]>
1 parent 86ed732 commit 524b9ba

File tree

271 files changed

+5974
-1247
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

271 files changed

+5974
-1247
lines changed

apps/web-antd/src/adapter/form.ts

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import type {
2+
BaseFormComponentType,
3+
VbenFormSchema as FormSchema,
4+
VbenFormProps,
5+
} from '@vben/common-ui';
6+
7+
import { h } from 'vue';
8+
9+
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
10+
import { $t } from '@vben/locales';
11+
12+
import {
13+
AutoComplete,
14+
Button,
15+
Checkbox,
16+
CheckboxGroup,
17+
DatePicker,
18+
Divider,
19+
Input,
20+
InputNumber,
21+
InputPassword,
22+
Mentions,
23+
Radio,
24+
RadioGroup,
25+
RangePicker,
26+
Rate,
27+
Select,
28+
Space,
29+
Switch,
30+
TimePicker,
31+
TreeSelect,
32+
Upload,
33+
} from 'ant-design-vue';
34+
35+
// 业务表单组件适配
36+
37+
export type FormComponentType =
38+
| 'AutoComplete'
39+
| 'Checkbox'
40+
| 'CheckboxGroup'
41+
| 'DatePicker'
42+
| 'Divider'
43+
| 'Input'
44+
| 'InputNumber'
45+
| 'InputPassword'
46+
| 'Mentions'
47+
| 'Radio'
48+
| 'RadioGroup'
49+
| 'RangePicker'
50+
| 'Rate'
51+
| 'Select'
52+
| 'Space'
53+
| 'Switch'
54+
| 'TimePicker'
55+
| 'TreeSelect'
56+
| 'Upload'
57+
| BaseFormComponentType;
58+
59+
// 初始化表单组件,并注册到form组件内部
60+
setupVbenForm<FormComponentType>({
61+
components: {
62+
AutoComplete,
63+
Checkbox,
64+
CheckboxGroup,
65+
DatePicker,
66+
// 自定义默认的重置按钮
67+
DefaultResetActionButton: (props, { attrs, slots }) => {
68+
return h(Button, { ...props, attrs, type: 'default' }, slots);
69+
},
70+
// 自定义默认的提交按钮
71+
DefaultSubmitActionButton: (props, { attrs, slots }) => {
72+
return h(Button, { ...props, attrs, type: 'primary' }, slots);
73+
},
74+
Divider,
75+
Input,
76+
InputNumber,
77+
InputPassword,
78+
Mentions,
79+
Radio,
80+
RadioGroup,
81+
RangePicker,
82+
Rate,
83+
Select,
84+
Space,
85+
Switch,
86+
TimePicker,
87+
TreeSelect,
88+
Upload,
89+
},
90+
config: {
91+
baseModelPropName: 'value',
92+
modelPropNameMap: {
93+
Checkbox: 'checked',
94+
Radio: 'checked',
95+
Switch: 'checked',
96+
Upload: 'fileList',
97+
},
98+
},
99+
defineRules: {
100+
required: (value, _params, ctx) => {
101+
if ((!value && value !== 0) || value.length === 0) {
102+
return $t('formRules.required', [ctx.label]);
103+
}
104+
return true;
105+
},
106+
},
107+
});
108+
109+
const useVbenForm = useForm<FormComponentType>;
110+
111+
export { useVbenForm, z };
112+
113+
export type VbenFormSchema = FormSchema<FormComponentType>;
114+
export type { VbenFormProps };

apps/web-antd/src/adapter/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './form';

apps/web-antd/src/layouts/basic.vue

+5-8
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@ import {
1313
UserDropdown,
1414
} from '@vben/layouts';
1515
import { preferences } from '@vben/preferences';
16-
import { storeToRefs, useAccessStore, useUserStore } from '@vben/stores';
16+
import { useAccessStore, useUserStore } from '@vben/stores';
1717
import { openWindow } from '@vben/utils';
1818
1919
import { $t } from '#/locales';
2020
import { useAuthStore } from '#/store';
21+
import LoginForm from '#/views/_core/authentication/login.vue';
2122
2223
const notifications = ref<NotificationItem[]>([
2324
{
@@ -87,8 +88,6 @@ const menus = computed(() => [
8788
},
8889
]);
8990
90-
const { loginLoading } = storeToRefs(authStore);
91-
9291
const avatar = computed(() => {
9392
return userStore.userInfo?.avatar ?? preferences.app.defaultAvatar;
9493
});
@@ -130,11 +129,9 @@ function handleMakeAll() {
130129
<AuthenticationLoginExpiredModal
131130
v-model:open="accessStore.loginExpired"
132131
:avatar
133-
:loading="loginLoading"
134-
password-placeholder="123456"
135-
username-placeholder="vben"
136-
@submit="authStore.authLogin"
137-
/>
132+
>
133+
<LoginForm />
134+
</AuthenticationLoginExpiredModal>
138135
</template>
139136
<template #lock-screen>
140137
<LockScreen :avatar @to-login="handleLogout" />

apps/web-antd/src/views/_core/authentication/code-login.vue

+39-5
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,49 @@
11
<script lang="ts" setup>
2-
import type { LoginCodeParams } from '@vben/common-ui';
2+
import type { LoginCodeParams, VbenFormSchema } from '@vben/common-ui';
33
4-
import { ref } from 'vue';
4+
import { computed, ref } from 'vue';
55
6-
import { AuthenticationCodeLogin } from '@vben/common-ui';
7-
import { LOGIN_PATH } from '@vben/constants';
6+
import { AuthenticationCodeLogin, z } from '@vben/common-ui';
7+
import { $t } from '@vben/locales';
88
99
defineOptions({ name: 'CodeLogin' });
1010
1111
const loading = ref(false);
1212
13+
const formSchema = computed((): VbenFormSchema[] => {
14+
return [
15+
{
16+
component: 'VbenInput',
17+
componentProps: {
18+
placeholder: $t('authentication.mobile'),
19+
},
20+
fieldName: 'phoneNumber',
21+
label: $t('authentication.mobile'),
22+
rules: z
23+
.string()
24+
.min(1, { message: $t('authentication.mobileTip') })
25+
.refine((v) => /^\d{11}$/.test(v), {
26+
message: $t('authentication.mobileErrortip'),
27+
}),
28+
},
29+
{
30+
component: 'VbenPinInput',
31+
componentProps: {
32+
createText: (countdown: number) => {
33+
const text =
34+
countdown > 0
35+
? $t('authentication.sendText', [countdown])
36+
: $t('authentication.sendCode');
37+
return text;
38+
},
39+
placeholder: $t('authentication.code'),
40+
},
41+
fieldName: 'code',
42+
label: $t('authentication.code'),
43+
rules: z.string().min(1, { message: $t('authentication.codeTip') }),
44+
},
45+
];
46+
});
1347
/**
1448
* 异步处理登录操作
1549
* Asynchronously handle the login process
@@ -23,8 +57,8 @@ async function handleLogin(values: LoginCodeParams) {
2357

2458
<template>
2559
<AuthenticationCodeLogin
60+
:form-schema="formSchema"
2661
:loading="loading"
27-
:login-path="LOGIN_PATH"
2862
@submit="handleLogin"
2963
/>
3064
</template>
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
<script lang="ts" setup>
2-
import { ref } from 'vue';
2+
import type { VbenFormSchema } from '@vben/common-ui';
33
4-
import { AuthenticationForgetPassword } from '@vben/common-ui';
5-
import { LOGIN_PATH } from '@vben/constants';
4+
import { computed, ref } from 'vue';
5+
6+
import { AuthenticationForgetPassword, z } from '@vben/common-ui';
7+
import { $t } from '@vben/locales';
68
79
defineOptions({ name: 'ForgetPassword' });
810
911
const loading = ref(false);
1012
13+
const formSchema = computed((): VbenFormSchema[] => {
14+
return [
15+
{
16+
component: 'VbenInput',
17+
componentProps: {
18+
placeholder: '[email protected]',
19+
},
20+
fieldName: 'email',
21+
label: $t('authentication.email'),
22+
rules: z
23+
.string()
24+
.min(1, { message: $t('authentication.emailTip') })
25+
.email($t('authentication.emailValidErrorTip')),
26+
},
27+
];
28+
});
29+
1130
function handleSubmit(value: string) {
1231
// eslint-disable-next-line no-console
1332
console.log('reset email:', value);
@@ -16,8 +35,8 @@ function handleSubmit(value: string) {
1635

1736
<template>
1837
<AuthenticationForgetPassword
38+
:form-schema="formSchema"
1939
:loading="loading"
20-
:login-path="LOGIN_PATH"
2140
@submit="handleSubmit"
2241
/>
2342
</template>
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,91 @@
11
<script lang="ts" setup>
2-
import { AuthenticationLogin } from '@vben/common-ui';
2+
import type { VbenFormSchema } from '@vben/common-ui';
3+
import type { BasicOption } from '@vben/types';
4+
5+
import { computed } from 'vue';
6+
7+
import { AuthenticationLogin, z } from '@vben/common-ui';
8+
import { $t } from '@vben/locales';
39
410
import { useAuthStore } from '#/store';
511
612
defineOptions({ name: 'Login' });
713
814
const authStore = useAuthStore();
15+
16+
const MOCK_USER_OPTIONS: BasicOption[] = [
17+
{
18+
label: '超级管理员',
19+
value: 'vben',
20+
},
21+
{
22+
label: '管理员',
23+
value: 'admin',
24+
},
25+
{
26+
label: '用户',
27+
value: 'jack',
28+
},
29+
];
30+
31+
const formSchema = computed((): VbenFormSchema[] => {
32+
return [
33+
{
34+
component: 'VbenSelect',
35+
componentProps: {
36+
options: MOCK_USER_OPTIONS,
37+
placeholder: $t('authentication.selectAccount'),
38+
},
39+
fieldName: 'selectAccount',
40+
label: $t('authentication.selectAccount'),
41+
rules: z
42+
.string()
43+
.min(1, { message: $t('authentication.selectAccount') })
44+
.optional()
45+
.default('vben'),
46+
},
47+
{
48+
component: 'VbenInput',
49+
componentProps: {
50+
placeholder: $t('authentication.usernameTip'),
51+
},
52+
dependencies: {
53+
trigger(values, form) {
54+
if (values.selectAccount) {
55+
const findUser = MOCK_USER_OPTIONS.find(
56+
(item) => item.value === values.selectAccount,
57+
);
58+
if (findUser) {
59+
form.setValues({
60+
password: '123456',
61+
username: findUser.value,
62+
});
63+
}
64+
}
65+
},
66+
triggerFields: ['selectAccount'],
67+
},
68+
fieldName: 'username',
69+
label: $t('authentication.username'),
70+
rules: z.string().min(1, { message: $t('authentication.usernameTip') }),
71+
},
72+
{
73+
component: 'VbenInputPassword',
74+
componentProps: {
75+
placeholder: $t('authentication.password'),
76+
},
77+
fieldName: 'password',
78+
label: $t('authentication.password'),
79+
rules: z.string().min(1, { message: $t('authentication.passwordTip') }),
80+
},
81+
];
82+
});
983
</script>
1084

1185
<template>
1286
<AuthenticationLogin
87+
:form-schema="formSchema"
1388
:loading="authStore.loginLoading"
14-
password-placeholder="123456"
15-
username-placeholder="vben"
1689
@submit="authStore.authLogin"
1790
/>
1891
</template>

0 commit comments

Comments
 (0)