Skip to content

Commit f98117f

Browse files
committed
feat: pass fieldsChanged into the handleValuesChange callback function
* fieldsChanged(已被改变值的字段名)将传入handleValuesChange回调函数
1 parent d18f561 commit f98117f

File tree

4 files changed

+48
-8
lines changed

4 files changed

+48
-8
lines changed

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
310310
| actionWrapperClass | 表单操作区域class | `any` | - |
311311
| handleReset | 表单重置回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
312312
| handleSubmit | 表单提交回调 | `(values: Record<string, any>,) => Promise<void> \| void` | - |
313-
| handleValuesChange | 表单值变化回调 | `(values: Record<string, any>,) => void` | - |
313+
| handleValuesChange | 表单值变化回调 | `(values: Record<string, any>, fieldsChanged: string[]) => void` | - |
314314
| actionButtonsReverse | 调换操作按钮位置 | `boolean` | `false` |
315315
| resetButtonOptions | 重置按钮组件参数 | `ActionButtonOptions` | - |
316316
| submitButtonOptions | 提交按钮组件参数 | `ActionButtonOptions` | - |
@@ -325,6 +325,12 @@ useVbenForm 返回的第二个参数,是一个对象,包含了一些表单
325325
| submitOnChange | 字段值改变时提交表单(内部防抖,这个属性一般用于表格的搜索表单) | `boolean` | false |
326326
| compact | 是否紧凑模式(忽略为校验信息所预留的空间) | `boolean` | false |
327327

328+
::: tip handleValuesChange
329+
330+
`handleValuesChange` 回调函数的第一个参数`values`装载了表单改变后的当前值对象,第二个参数`fieldsChanged`是一个数组,包含了所有被改变的字段名。注意:第二个参数仅在v5.5.4(不含)以上版本可用。
331+
332+
:::
333+
328334
::: tip fieldMappingTime
329335

330336
此属性用于将表单内的数组值映射成 2 个字段,它应当传入一个数组,数组的每一项是一个映射规则,规则的第一个成员是一个字符串,表示需要映射的字段名,第二个成员是一个数组,表示映射后的字段名,第三个成员是一个可选的格式掩码,用于格式化日期时间字段;也可以提供一个格式化函数(参数分别为当前值和当前字段名,返回格式化后的值)。如果明确地将格式掩码设为null,则原值映射而不进行格式化(适用于非日期时间字段)。例如:`[['timeRange', ['startTime', 'endTime'], 'YYYY-MM-DD']]``timeRange`应当是一个至少具有2个成员的数组类型的值。Form会将`timeRange`的值前两个值分别按照格式掩码`YYYY-MM-DD`格式化后映射到`startTime``endTime`字段上。每一项的第三个参数是一个可选的格式掩码,

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,10 @@ export interface VbenFormProps<
378378
/**
379379
* 表单值变化回调
380380
*/
381-
handleValuesChange?: (values: Record<string, any>) => void;
381+
handleValuesChange?: (
382+
values: Record<string, any>,
383+
fieldsChanged: string[],
384+
) => void;
382385
/**
383386
* 重置按钮参数
384387
*/

packages/@core/ui-kit/form-ui/src/vben-use-form.vue

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
<script setup lang="ts">
2+
import type { Recordable } from '@vben-core/typings';
3+
24
import type { ExtendedFormApi, VbenFormProps } from './types';
35
46
// import { toRaw, watch } from 'vue';
57
import { nextTick, onMounted, watch } from 'vue';
6-
// import { isFunction } from '@vben-core/shared/utils';
78
89
import { useForwardPriorityValues } from '@vben-core/composables';
9-
import { cloneDeep } from '@vben-core/shared/utils';
10+
import { cloneDeep, get, isEqual, set } from '@vben-core/shared/utils';
1011
1112
import { useDebounceFn } from '@vueuse/core';
1213
@@ -61,16 +62,43 @@ function handleKeyDownEnter(event: KeyboardEvent) {
6162
}
6263
6364
const handleValuesChangeDebounced = useDebounceFn(async () => {
64-
forward.value.handleValuesChange?.(
65-
cloneDeep(await forward.value.formApi.getValues()),
66-
);
6765
state.value.submitOnChange && forward.value.formApi?.validateAndSubmitForm();
6866
}, 300);
6967
68+
const valuesCache: Recordable<any> = {};
69+
7070
onMounted(async () => {
7171
// 只在挂载后开始监听,form.values会有一个初始化的过程
7272
await nextTick();
73-
watch(() => form.values, handleValuesChangeDebounced, { deep: true });
73+
watch(
74+
() => form.values,
75+
(newVal) => {
76+
if (forward.value.handleValuesChange) {
77+
const fields = state.value.schema?.map((item) => {
78+
return item.fieldName;
79+
});
80+
81+
if (fields && fields.length > 0) {
82+
const changedFields: string[] = [];
83+
fields.forEach((field) => {
84+
const newFieldValue = get(newVal, field);
85+
const oldFieldValue = get(valuesCache, field);
86+
if (!isEqual(newFieldValue, oldFieldValue)) {
87+
changedFields.push(field);
88+
set(valuesCache, field, newFieldValue);
89+
}
90+
});
91+
92+
if (changedFields.length > 0) {
93+
// 调用handleValuesChange回调,传入所有表单值的深拷贝和变更的字段列表
94+
forward.value.handleValuesChange(cloneDeep(newVal), changedFields);
95+
}
96+
}
97+
}
98+
handleValuesChangeDebounced();
99+
},
100+
{ deep: true },
101+
);
74102
});
75103
</script>
76104

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ const [BaseForm, baseFormApi] = useVbenForm({
4242
fieldMappingTime: [['rangePicker', ['startTime', 'endTime'], 'YYYY-MM-DD']],
4343
// 提交函数
4444
handleSubmit: onSubmit,
45+
handleValuesChange(_values, fieldsChanged) {
46+
message.info(`表单以下字段发生变化:${fieldsChanged.join('')}`);
47+
},
4548
4649
// 垂直布局,label和input在不同行,值为vertical
4750
// 水平布局,label和input在同一行

0 commit comments

Comments
 (0)