,
+ fieldName: string,
+ value: any,
+ ) {
+ const { rawKey } = resolveFieldNamePath(fieldName);
+ if (rawKey) {
+ values[rawKey] = value;
+ return;
+ }
+
+ set(values, fieldName, value);
+ }
+
private updateState() {
const currentSchema = this.state?.schema ?? [];
const prevSchema = this.prevState?.schema ?? [];
diff --git a/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts b/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts
index 2a330c9f6..8813beadc 100644
--- a/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts
+++ b/packages/@core/ui-kit/form-ui/src/form-render/dependencies.ts
@@ -10,6 +10,7 @@ import { get, isBoolean, isFunction } from '@vben-core/shared/utils';
import { useFormValues } from 'vee-validate';
+import { resolveFieldNamePath } from '../field-name';
import { injectRenderFormProps } from './context';
/**
@@ -22,8 +23,8 @@ function resolveValueByFieldName(
fieldName: string,
) {
// vee-validate:[] 表示禁用嵌套
- if (fieldName.startsWith('[') && fieldName.endsWith(']')) {
- const rawKey = fieldName.slice(1, -1);
+ const { rawKey } = resolveFieldNamePath(fieldName);
+ if (rawKey) {
return values[rawKey];
}
diff --git a/packages/@core/ui-kit/form-ui/src/types.ts b/packages/@core/ui-kit/form-ui/src/types.ts
index e30e8f14f..78114ee30 100644
--- a/packages/@core/ui-kit/form-ui/src/types.ts
+++ b/packages/@core/ui-kit/form-ui/src/types.ts
@@ -228,6 +228,19 @@ type MappedComponentProps =
) => P & Record)
| (P & Record);
+/**
+ * 格式化 `getValues()` 输出中的当前字段值。
+ * - 返回 `undefined`:保留当前字段已被移除的状态,通常配合 `setValue(key, nextValue)`
+ * 把一个字段拆分写入到其他字段,例如 `startTime` / `endTime`
+ * - 返回其他值:会将当前字段恢复/写回为该返回值
+ * - `setValue` 回调签名为 `(key, nextValue) => void`
+ */
+export type FormValueFormat = (
+ value: any,
+ setValue: (fieldName: string, value: any) => void,
+ values: Record,
+) => any;
+
interface FormSchemaBody extends Omit {
/** 默认值 */
defaultValue?: any;
@@ -249,6 +262,12 @@ interface FormSchemaBody extends Omit {
rules?: FormSchemaRuleType;
/** 后缀 */
suffix?: CustomRenderType;
+ /**
+ * 获取表单值时格式化当前字段。
+ * - 返回值不为 `undefined` 时,会回写到当前 fieldName
+ * - 返回值为 `undefined` 时,可通过 setValue 写入一个或多个目标字段
+ */
+ valueFormat?: FormValueFormat;
}
type FormSchemaDiscriminated<
diff --git a/playground/src/locales/langs/en-US/examples.json b/playground/src/locales/langs/en-US/examples.json
index 4e65d7fbf..d60062174 100644
--- a/playground/src/locales/langs/en-US/examples.json
+++ b/playground/src/locales/langs/en-US/examples.json
@@ -14,6 +14,7 @@
"basic": "Basic Form",
"layout": "Custom Layout",
"query": "Query Form",
+ "valueFormat": "Value Format",
"rules": "Form Rules",
"dynamic": "Dynamic Form",
"custom": "Custom Component",
diff --git a/playground/src/locales/langs/zh-CN/examples.json b/playground/src/locales/langs/zh-CN/examples.json
index 22e9e2933..6a5be2358 100644
--- a/playground/src/locales/langs/zh-CN/examples.json
+++ b/playground/src/locales/langs/zh-CN/examples.json
@@ -17,6 +17,7 @@
"basic": "基础表单",
"layout": "自定义布局",
"query": "查询表单",
+ "valueFormat": "值格式化",
"rules": "表单校验",
"dynamic": "动态表单",
"custom": "自定义组件",
diff --git a/playground/src/router/routes/modules/examples.ts b/playground/src/router/routes/modules/examples.ts
index a0cedc09c..5bac90ac3 100644
--- a/playground/src/router/routes/modules/examples.ts
+++ b/playground/src/router/routes/modules/examples.ts
@@ -37,6 +37,14 @@ const routes: RouteRecordRaw[] = [
title: $t('examples.form.query'),
},
},
+ {
+ name: 'FormValueFormatExample',
+ path: '/examples/form/value-format',
+ component: () => import('#/views/examples/form/value-format.vue'),
+ meta: {
+ title: $t('examples.form.valueFormat'),
+ },
+ },
{
name: 'FormRulesExample',
path: '/examples/form/rules',
diff --git a/playground/src/views/examples/form/value-format.vue b/playground/src/views/examples/form/value-format.vue
new file mode 100644
index 000000000..bf1449f88
--- /dev/null
+++ b/playground/src/views/examples/form/value-format.vue
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+ form.values 保持组件原始值,getValues() /
+ 提交时会按 schema.valueFormat 输出转换后的 payload。
+
+
+ return 值:回写当前字段
+ setValue:拆分写入其他字段
+ return undefined:保持原字段删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ liveValuesPreview
+ }}
+
+
+ {{
+ transformedValuesPreview
+ }}
+
+
+
+