Skip to content

Commit 958c8b4

Browse files
authored
feat: imporve naive form component (#5071)
1 parent 3737666 commit 958c8b4

File tree

5 files changed

+156
-2
lines changed

5 files changed

+156
-2
lines changed

apps/web-naive/src/adapter/component/index.ts

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import {
1919
NDivider,
2020
NInput,
2121
NInputNumber,
22+
NRadio,
23+
NRadioButton,
2224
NRadioGroup,
2325
NSelect,
2426
NSpace,
@@ -78,7 +80,22 @@ async function initComponentAdapter() {
7880
);
7981
},
8082
Checkbox: NCheckbox,
81-
CheckboxGroup: NCheckboxGroup,
83+
CheckboxGroup: (props, { attrs, slots }) => {
84+
let defaultSlot;
85+
if (Reflect.has(slots, 'default')) {
86+
defaultSlot = slots.default;
87+
} else {
88+
const { options } = attrs;
89+
if (Array.isArray(options)) {
90+
defaultSlot = () => options.map((option) => h(NCheckbox, option));
91+
}
92+
}
93+
return h(
94+
NCheckboxGroup,
95+
{ ...props, ...attrs },
96+
{ default: defaultSlot },
97+
);
98+
},
8299
DatePicker: NDatePicker,
83100
// 自定义默认按钮
84101
DefaultButton: (props, { attrs, slots }) => {
@@ -98,7 +115,28 @@ async function initComponentAdapter() {
98115
},
99116
Input: withDefaultPlaceholder(NInput, 'input'),
100117
InputNumber: withDefaultPlaceholder(NInputNumber, 'input'),
101-
RadioGroup: NRadioGroup,
118+
RadioGroup: (props, { attrs, slots }) => {
119+
let defaultSlot;
120+
if (Reflect.has(slots, 'default')) {
121+
defaultSlot = slots.default;
122+
} else {
123+
const { options } = attrs;
124+
if (Array.isArray(options)) {
125+
defaultSlot = () =>
126+
options.map((option) =>
127+
h(attrs.isButton ? NRadioButton : NRadio, option),
128+
);
129+
}
130+
}
131+
const groupRender = h(
132+
NRadioGroup,
133+
{ ...props, ...attrs },
134+
{ default: defaultSlot },
135+
);
136+
return attrs.isButton
137+
? h(NSpace, { vertical: true }, () => groupRender)
138+
: groupRender;
139+
},
102140
Select: withDefaultPlaceholder(NSelect, 'select'),
103141
Space: NSpace,
104142
Switch: NSwitch,

apps/web-naive/src/locales/langs/en-US/demos.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"title": "Demos",
33
"naive": "Naive UI",
44
"table": "Table",
5+
"form": "Form",
56
"vben": {
67
"title": "Project",
78
"about": "About",

apps/web-naive/src/locales/langs/zh-CN/demos.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"title": "演示",
33
"naive": "Naive UI",
44
"table": "Table",
5+
"form": "表单",
56
"vben": {
67
"title": "项目",
78
"about": "关于",

apps/web-naive/src/router/routes/modules/demos.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ const routes: RouteRecordRaw[] = [
3131
path: '/demos/table',
3232
component: () => import('#/views/demos/table/index.vue'),
3333
},
34+
{
35+
meta: {
36+
title: $t('demos.form'),
37+
},
38+
name: 'Form',
39+
path: '/demos/form',
40+
component: () => import('#/views/demos/form/basic.vue'),
41+
},
3442
],
3543
},
3644
];
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<script lang="ts" setup>
2+
import { Page } from '@vben/common-ui';
3+
4+
import { NButton, NCard, useMessage } from 'naive-ui';
5+
6+
import { useVbenForm } from '#/adapter/form';
7+
8+
const message = useMessage();
9+
const [Form, formApi] = useVbenForm({
10+
commonConfig: {
11+
// 所有表单项
12+
componentProps: {
13+
class: 'w-full',
14+
},
15+
},
16+
layout: 'horizontal',
17+
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
18+
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
19+
handleSubmit: (values) => {
20+
message.success(`表单数据:${JSON.stringify(values)}`);
21+
},
22+
schema: [
23+
{
24+
component: 'Input',
25+
fieldName: 'string',
26+
label: 'String',
27+
},
28+
{
29+
component: 'InputNumber',
30+
fieldName: 'number',
31+
label: 'Number',
32+
},
33+
{
34+
component: 'RadioGroup',
35+
fieldName: 'radio',
36+
label: 'Radio',
37+
componentProps: {
38+
options: [
39+
{ value: 'A', label: 'A' },
40+
{ value: 'B', label: 'B' },
41+
{ value: 'C', label: 'C' },
42+
{ value: 'D', label: 'D' },
43+
{ value: 'E', label: 'E' },
44+
],
45+
},
46+
},
47+
{
48+
component: 'RadioGroup',
49+
fieldName: 'radioButton',
50+
label: 'RadioButton',
51+
componentProps: {
52+
isButton: true,
53+
class: 'flex flex-wrap', // 如果选项过多,可以添加class来自动折叠
54+
options: [
55+
{ value: 'A', label: '选项A' },
56+
{ value: 'B', label: '选项B' },
57+
{ value: 'C', label: '选项C' },
58+
{ value: 'D', label: '选项D' },
59+
{ value: 'E', label: '选项E' },
60+
{ value: 'F', label: '选项F' },
61+
],
62+
},
63+
},
64+
{
65+
component: 'CheckboxGroup',
66+
fieldName: 'checkbox',
67+
label: 'Checkbox',
68+
componentProps: {
69+
options: [
70+
{ value: 'A', label: '选项A' },
71+
{ value: 'B', label: '选项B' },
72+
{ value: 'C', label: '选项C' },
73+
],
74+
},
75+
},
76+
{
77+
component: 'DatePicker',
78+
fieldName: 'date',
79+
label: 'Date',
80+
},
81+
],
82+
});
83+
function setFormValues() {
84+
formApi.setValues({
85+
string: 'string',
86+
number: 123,
87+
radio: 'B',
88+
radioButton: 'C',
89+
checkbox: ['A', 'C'],
90+
date: Date.now(),
91+
});
92+
}
93+
</script>
94+
<template>
95+
<Page
96+
description="表单适配器重新包装了CheckboxGroup和RadioGroup,可以通过options属性传递选项数据(选项数据将作为子组件的属性)"
97+
title="表单演示"
98+
>
99+
<NCard title="基础表单">
100+
<template #header-extra>
101+
<NButton type="primary" @click="setFormValues">设置表单值</NButton>
102+
</template>
103+
<Form />
104+
</NCard>
105+
</Page>
106+
</template>

0 commit comments

Comments
 (0)