Skip to content

Commit 9fc5944

Browse files
perf: 优化useVbenForm样式 (#6611)
* perf(style): 优化useVbenForm垂直布局 actions 样式 * perf(style): 优化useVbenForm actions 布局样式 - 操作按钮组显示位置 ``` actionPosition?: 'center' | 'left' | 'right'; ``` - 操作按钮组的样式 ``` actionType?: 'block' | 'inline' inline: 行类显示,block: 新一行单独显示 ``` * perf: 优化useVbenForm actions 布局样式 删除 actionType 增加 actionLayout - actionLayout?: 'inline' | 'newLine' | 'rowEnd'; - newLine: 在新行显示。rowEnd: 在行内显示,靠右对齐(默认)。inline: 使用grid默认样式 - 删除无用代码 queryFormStyle * perf: 优化useVbenForm使用案例 * perf: 优化form组件样式 去掉padding,改为gap * docs: update vben-form.md * fix: 修复FormMessage位置 * perf: Avoid direct mutation of props object. - props.actionLayout = props.actionLayout || 'rowEnd'; - props.actionPosition = props.actionPosition || 'right'; + const actionLayout = props.actionLayout || 'rowEnd'; + const actionPosition = props.actionPosition || 'right'; Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fix: 修复 wrapperClass 权重 * fix: 全局搜索结果不匹配 #6603 * fix: 避免FormMessage溢出 --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
1 parent b93e22c commit 9fc5944

File tree

7 files changed

+141
-28
lines changed

7 files changed

+141
-28
lines changed

docs/src/components/common-ui/vben-form.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,8 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
308308
| showCollapseButton | 是否显示折叠按钮 | `boolean` | `false` |
309309
| wrapperClass | 表单的布局,基于tailwindcss | `any` | - |
310310
| actionWrapperClass | 表单操作区域class | `any` | - |
311+
| actionLayout | 表单操作按钮位置 | `'newLine' \| 'rowEnd' \| 'inline'` | `rowEnd` |
312+
| actionPosition | 表单操作按钮对齐方式 | `'left' \| 'center' \| 'right'` | `right` |
311313
| handleReset | 表单重置回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
312314
| handleSubmit | 表单提交回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
313315
| handleValuesChange | 表单值变化回调 | `(values: Record<string, any>, fieldsChanged: string[]) => void` | - |

packages/@core/ui-kit/form-ui/src/components/form-actions.vue

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,6 @@ const submitButtonOptions = computed(() => {
3434
// return !!unref(rootProps).showCollapseButton;
3535
// });
3636
37-
const queryFormStyle = computed(() => {
38-
if (!unref(rootProps).actionWrapperClass) {
39-
return {
40-
'grid-column': `-2 / -1`,
41-
marginLeft: 'auto',
42-
};
43-
}
44-
45-
return {};
46-
});
47-
4837
async function handleSubmit(e: Event) {
4938
e?.preventDefault();
5039
e?.stopPropagation();
@@ -86,30 +75,66 @@ watch(
8675
},
8776
);
8877
78+
const actionWrapperClass = computed(() => {
79+
const props = unref(rootProps);
80+
const actionLayout = props.actionLayout || 'rowEnd';
81+
const actionPosition = props.actionPosition || 'right';
82+
83+
const cls = [
84+
'flex',
85+
'w-full',
86+
'items-center',
87+
'gap-3',
88+
props.compact ? 'pb-2' : 'pb-4',
89+
props.layout === 'vertical' ? 'self-end' : 'self-center',
90+
props.actionWrapperClass,
91+
];
92+
93+
switch (actionLayout) {
94+
case 'newLine': {
95+
cls.push('col-span-full');
96+
break;
97+
}
98+
case 'rowEnd': {
99+
cls.push('col-[-2/-1]');
100+
break;
101+
}
102+
// 'inline' 不需要额外类名,保持默认
103+
}
104+
105+
switch (actionPosition) {
106+
case 'center': {
107+
cls.push('justify-center');
108+
break;
109+
}
110+
case 'left': {
111+
cls.push('justify-start');
112+
break;
113+
}
114+
default: {
115+
// case 'right': 默认右对齐
116+
cls.push('justify-end');
117+
break;
118+
}
119+
}
120+
121+
return cls.join(' ');
122+
});
123+
89124
defineExpose({
90125
handleReset,
91126
handleSubmit,
92127
});
93128
</script>
94129
<template>
95-
<div
96-
:class="
97-
cn(
98-
'col-span-full w-full text-right',
99-
rootProps.compact ? 'pb-2' : 'pb-6',
100-
rootProps.actionWrapperClass,
101-
)
102-
"
103-
:style="queryFormStyle"
104-
>
130+
<div :class="cn(actionWrapperClass)">
105131
<template v-if="rootProps.actionButtonsReverse">
106132
<!-- 提交按钮前 -->
107133
<slot name="submit-before"></slot>
108134

109135
<component
110136
:is="COMPONENT_MAP.PrimaryButton"
111137
v-if="submitButtonOptions.show"
112-
class="ml-3"
113138
type="button"
114139
@click="handleSubmit"
115140
v-bind="submitButtonOptions"
@@ -124,7 +149,6 @@ defineExpose({
124149
<component
125150
:is="COMPONENT_MAP.DefaultButton"
126151
v-if="resetButtonOptions.show"
127-
class="ml-3"
128152
type="button"
129153
@click="handleReset"
130154
v-bind="resetButtonOptions"
@@ -139,7 +163,6 @@ defineExpose({
139163
<component
140164
:is="COMPONENT_MAP.PrimaryButton"
141165
v-if="submitButtonOptions.show"
142-
class="ml-3"
143166
type="button"
144167
@click="handleSubmit"
145168
v-bind="submitButtonOptions"
@@ -152,9 +175,9 @@ defineExpose({
152175
<slot name="expand-before"></slot>
153176

154177
<VbenExpandableArrow
178+
class="ml-[-0.3em]"
155179
v-if="rootProps.showCollapseButton"
156180
v-model:model-value="collapsed"
157-
class="ml-2"
158181
>
159182
<span>{{ collapsed ? $t('expand') : $t('collapse') }}</span>
160183
</VbenExpandableArrow>

packages/@core/ui-kit/form-ui/src/form-render/form-field.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ onUnmounted(() => {
295295
'form-is-required': shouldRequired,
296296
'flex-col': isVertical,
297297
'flex-row items-center': !isVertical,
298-
'pb-6': !compact,
298+
'pb-4': !compact,
299299
'pb-2': compact,
300300
}"
301301
class="relative flex"
@@ -386,7 +386,7 @@ onUnmounted(() => {
386386
</div>
387387

388388
<Transition name="slide-up" v-if="!compact">
389-
<FormMessage class="absolute bottom-1" />
389+
<FormMessage class="absolute" />
390390
</Transition>
391391
</div>
392392
</FormItem>

packages/@core/ui-kit/form-ui/src/form-render/form.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ const emits = defineEmits<{
4141
submit: [event: any];
4242
}>();
4343
44+
const wrapperClass = computed(() => {
45+
const cls = ['flex flex-col'];
46+
if (props.layout === 'vertical') {
47+
cls.push(props.compact ? 'gap-x-2' : 'gap-x-4');
48+
} else {
49+
cls.push('gap-2');
50+
}
51+
return cn(...cls, props.wrapperClass);
52+
});
53+
4454
provideFormRenderProps(props);
4555
4656
const { isCalculated, keepFormItemIndex, wrapperRef } = useExpandable(props);

packages/@core/ui-kit/form-ui/src/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,15 @@ export interface VbenFormProps<
354354
* 操作按钮是否反转(提交按钮前置)
355355
*/
356356
actionButtonsReverse?: boolean;
357+
/**
358+
* 操作按钮组的样式
359+
* newLine: 在新行显示。rowEnd: 在行内显示,靠右对齐(默认)。inline: 使用grid默认样式
360+
*/
361+
actionLayout?: 'inline' | 'newLine' | 'rowEnd';
362+
/**
363+
* 操作按钮组显示位置,默认靠右显示
364+
*/
365+
actionPosition?: 'center' | 'left' | 'right';
357366
/**
358367
* 表单操作区域class
359368
*/

packages/effects/layouts/src/widgets/global-search/search-panel.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ async function handleEnter() {
9898
}
9999
const to = result[index];
100100
if (to) {
101-
searchHistory.value.push(to);
101+
searchHistory.value = uniqueByField([...searchHistory.value, to], 'path');
102102
handleClose();
103103
await nextTick();
104104
if (isHttpUrl(to.path)) {

playground/src/views/examples/form/query.vue

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,70 @@ const [QueryForm1] = useVbenForm({
125125
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
126126
});
127127
128+
const [QueryForm2] = useVbenForm({
129+
// 操作按钮组 newLine: 在新行显示。rowEnd: 在行内显示,靠右对齐(默认)。inline: 使用grid默认样式
130+
actionLayout: 'newLine',
131+
actionPosition: 'left', // 操作按钮组在左侧显示
132+
// 默认折叠
133+
collapsed: true,
134+
collapsedRows: 3,
135+
// 所有表单项共用,可单独在表单内覆盖
136+
commonConfig: {
137+
// 所有表单项
138+
componentProps: {
139+
class: 'w-full',
140+
},
141+
},
142+
// 提交函数
143+
handleSubmit: onSubmit,
144+
// 垂直布局,label和input在不同行,值为vertical
145+
// 水平布局,label和input在同一行
146+
layout: 'vertical',
147+
schema: [
148+
{
149+
// 组件需要在 #/adapter.ts内注册,并加上类型
150+
component: 'Input',
151+
// 对应组件的参数
152+
componentProps: {
153+
placeholder: '请输入用户名',
154+
},
155+
// 字段名
156+
fieldName: 'username',
157+
// 界面显示的label
158+
label: '字符串',
159+
},
160+
{
161+
component: 'InputPassword',
162+
componentProps: {
163+
placeholder: '请输入密码',
164+
},
165+
fieldName: 'password',
166+
label: '密码',
167+
},
168+
{
169+
component: 'InputNumber',
170+
componentProps: {
171+
placeholder: '请输入',
172+
},
173+
fieldName: 'number',
174+
label: '数字(带后缀)',
175+
suffix: () => '¥',
176+
},
177+
{
178+
component: 'DatePicker',
179+
fieldName: 'datePicker',
180+
label: '日期选择框',
181+
},
182+
],
183+
// 是否可展开
184+
showCollapseButton: true,
185+
submitButtonOptions: {
186+
content: '查询',
187+
},
188+
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
189+
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
190+
});
191+
128192
function onSubmit(values: Record<string, any>) {
129193
message.success({
130194
content: `form values: ${JSON.stringify(values)}`,
@@ -140,6 +204,11 @@ function onSubmit(values: Record<string, any>) {
140204
<Card class="mb-5" title="查询表单,默认展开">
141205
<QueryForm />
142206
</Card>
207+
208+
<Card class="mb-5" title="查询表单,默认展开,垂直布局">
209+
<QueryForm2 />
210+
</Card>
211+
143212
<Card title="查询表单,默认折叠,折叠时保留2行">
144213
<QueryForm1 />
145214
</Card>

0 commit comments

Comments
 (0)