feat: form colon support (#5156)

This commit is contained in:
Netfan 2024-12-16 22:37:29 +08:00 committed by GitHub
parent 38805a0e1f
commit 593916d6aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 33 additions and 11 deletions

View File

@ -313,14 +313,14 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
| resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - | | resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - |
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - | | submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |
| showDefaultActions | 是否显示默认操作按钮 | `boolean` | `true` | | showDefaultActions | 是否显示默认操作按钮 | `boolean` | `true` |
| collapsed | 是否折叠,在`是否展开在showCollapseButton=true`时生效 | `boolean` | `false` | | collapsed | 是否折叠,在`showCollapseButton`为`true`时生效 | `boolean` | `false` |
| collapseTriggerResize | 折叠时,触发`resize`事件 | `boolean` | `false` | | collapseTriggerResize | 折叠时,触发`resize`事件 | `boolean` | `false` |
| collapsedRows | 折叠时保持的行数 | `number` | `1` | | collapsedRows | 折叠时保持的行数 | `number` | `1` |
| fieldMappingTime | 用于将表单内时间区域的应设成 2 个字段 | `[string, [string, string], string?][]` | - | | fieldMappingTime | 用于将表单内时间区域组件的数组值映射成 2 个字段 | `[string, [string, string], string?][]` | - |
| commonConfig | 表单项的通用配置,每个配置都会传递到每个表单项,表单项可覆盖 | `FormCommonConfig` | - | | commonConfig | 表单项的通用配置,每个配置都会传递到每个表单项,表单项可覆盖 | `FormCommonConfig` | - |
| schema | 表单项的每一项配置 | `FormSchema` | - | | schema | 表单项的每一项配置 | `FormSchema[]` | - |
| submitOnEnter | 按下回车健时提交表单 | `boolean` | false | | submitOnEnter | 按下回车健时提交表单 | `boolean` | false |
| submitOnChange | 字段值改变时提交表单 | `boolean` | false | | submitOnChange | 字段值改变时提交表单(内部防抖,这个属性一般用于表格的搜索表单) | `boolean` | false |
### TS 类型说明 ### TS 类型说明
@ -361,6 +361,10 @@ export interface FormCommonConfig {
* 所有表单项的控件样式 * 所有表单项的控件样式
*/ */
controlClass?: string; controlClass?: string;
/**
* 在表单项的Label后显示一个冒号
*/
colon?: boolean;
/** /**
* 所有表单项的禁用状态 * 所有表单项的禁用状态
* @default false * @default false
@ -420,7 +424,7 @@ export interface FormSchema<
dependencies?: FormItemDependencies; dependencies?: FormItemDependencies;
/** 描述 */ /** 描述 */
description?: string; description?: string;
/** 字段名 */ /** 字段名,也作为自定义插槽的名称 */
fieldName: string; fieldName: string;
/** 帮助信息 */ /** 帮助信息 */
help?: string; help?: string;
@ -443,7 +447,7 @@ export interface FormSchema<
```ts ```ts
dependencies: { dependencies: {
// 只有当 name 字段的值变化时,才会触发联动 // 触发字段。只有这些字段值变动时,联动才会触发
triggerFields: ['name'], triggerFields: ['name'],
// 动态判断当前字段是否需要显示,不显示则直接销毁 // 动态判断当前字段是否需要显示,不显示则直接销毁
if(values,formApi){}, if(values,formApi){},
@ -464,11 +468,11 @@ dependencies: {
### 表单校验 ### 表单校验
表单联动需要通过 schema 内的 `rules` 属性进行配置。 表单校验需要通过 schema 内的 `rules` 属性进行配置。
rules的值可以是一个字符串也可以是一个zod的schema。 rules的值可以是字符串(预定义的校验规则名称)也可以是一个zod的schema。
#### 字符串 #### 预定义的校验规则
```ts ```ts
// 表示字段必填默认会根据适配器的required进行国际化 // 表示字段必填默认会根据适配器的required进行国际化
@ -494,11 +498,16 @@ import { z } from '#/adapter/form';
rules: z.string().min(1, { message: '请输入字符串' }); rules: z.string().min(1, { message: '请输入字符串' });
} }
// 可选,并且携带默认值 // 可选(可以是undefined),并且携带默认值。注意zod的optional不包括空字符串''
{ {
rules: z.string().default('默认值').optional(), rules: z.string().default('默认值').optional(),
} }
// 可以是空字符串、undefined或者一个邮箱地址
{
rules: z.union(z.string().email().optional(), z.literal(""))
}
// 复杂校验 // 复杂校验
{ {
z.string().min(1, { message: "请输入" }) z.string().min(1, { message: "请输入" })

View File

@ -26,6 +26,7 @@ import { isEventObjectLike } from './helper';
interface Props extends FormSchema {} interface Props extends FormSchema {}
const { const {
colon,
commonComponentProps, commonComponentProps,
component, component,
componentProps, componentProps,
@ -300,7 +301,10 @@ function autofocus() {
:required="shouldRequired && !hideRequiredMark" :required="shouldRequired && !hideRequiredMark"
:style="labelStyle" :style="labelStyle"
> >
{{ label }} <template v-if="label">
<span>{{ label }}</span>
<span v-if="colon" class="ml-[2px]">:</span>
</template>
</FormLabel> </FormLabel>
<div :class="cn('relative flex w-full items-center', wrapperClass)"> <div :class="cn('relative flex w-full items-center', wrapperClass)">
<FormControl :class="cn(controlClass)"> <FormControl :class="cn(controlClass)">

View File

@ -86,6 +86,7 @@ const computedSchema = computed(
formFieldProps: Record<string, any>; formFieldProps: Record<string, any>;
} & Omit<FormSchema, 'formFieldProps'>)[] => { } & Omit<FormSchema, 'formFieldProps'>)[] => {
const { const {
colon = false,
componentProps = {}, componentProps = {},
controlClass = '', controlClass = '',
disabled, disabled,
@ -110,6 +111,7 @@ const computedSchema = computed(
: false; : false;
return { return {
colon,
disabled, disabled,
disabledOnChangeListener, disabledOnChangeListener,
disabledOnInputListener, disabledOnInputListener,

View File

@ -136,6 +136,10 @@ type ComponentProps =
| MaybeComponentProps; | MaybeComponentProps;
export interface FormCommonConfig { export interface FormCommonConfig {
/**
* Label后显示一个冒号
*/
colon?: boolean;
/** /**
* props * props
*/ */

View File

@ -16,6 +16,8 @@ const activeTab = ref('basic');
const [BaseForm, baseFormApi] = useVbenForm({ const [BaseForm, baseFormApi] = useVbenForm({
// //
commonConfig: { commonConfig: {
// label
colon: true,
// //
componentProps: { componentProps: {
class: 'w-full', class: 'w-full',
@ -40,6 +42,7 @@ const [BaseForm, baseFormApi] = useVbenForm({
fieldName: 'username', fieldName: 'username',
// label // label
label: '字符串', label: '字符串',
rules: 'required',
}, },
{ {
// #/adapter.ts // #/adapter.ts