@zat-design/sisyphus-react 4.4.3-beta.2 → 4.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -42
- package/es/ProEditTable/components/RenderField/ListChangedWrapper.d.ts +1 -14
- package/es/ProEditTable/components/RenderField/ListChangedWrapper.js +27 -102
- package/es/ProEditTable/components/RenderField/index.js +267 -362
- package/es/ProEditTable/components/RenderField/propsType.d.ts +30 -0
- package/es/ProEditTable/components/RenderField/propsType.js +1 -0
- package/es/ProEditTable/components/RenderField/tools.d.ts +22 -0
- package/es/ProEditTable/components/RenderField/tools.js +203 -0
- package/es/ProForm/components/combination/Group/utils/index.d.ts +22 -22
- package/es/ProTree/components/ProTreeSelect/index.js +3 -2
- package/es/ProTree/utils.d.ts +9 -0
- package/es/ProTree/utils.js +31 -0
- package/package.json +1 -2
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import _get from "lodash/get";
|
|
2
|
-
import _isEqualWith from "lodash/isEqualWith";
|
|
3
2
|
import _isFunction from "lodash/isFunction";
|
|
4
3
|
import _omit from "lodash/omit";
|
|
5
4
|
import _debounce from "lodash/debounce";
|
|
@@ -10,7 +9,7 @@ import _cloneDeep from "lodash/cloneDeep";
|
|
|
10
9
|
import React, { useEffect, useCallback, useMemo, memo, useRef } from 'react';
|
|
11
10
|
import { Form } from 'antd';
|
|
12
11
|
import classNames from 'classnames';
|
|
13
|
-
import { compatStartTransition
|
|
12
|
+
import { compatStartTransition } from "../../../utils";
|
|
14
13
|
import valueTypeMap from "../../../ProForm/utils/valueType";
|
|
15
14
|
import transformMap from "../../utils/transform";
|
|
16
15
|
import { getNamePath, difference, getDisabled } from "../../utils/tools";
|
|
@@ -26,11 +25,8 @@ import ConfirmWrapper from "../../../ProForm/components/render/ConfirmWrapper";
|
|
|
26
25
|
import { getDefaultProps } from "../../utils/getDefaultProps";
|
|
27
26
|
import ListChangedWrapper from "./ListChangedWrapper";
|
|
28
27
|
import useShouldUpdateForTable from "../../utils/useShouldUpdateForTable";
|
|
29
|
-
|
|
30
|
-
/** 列配置中不应透传到 Form.Item 或 DOM 的字段(与 ProForm Render 保持一致) */
|
|
28
|
+
import { OMIT_FORM_ITEM_AND_DOM_KEYS, arePropsEqual } from "./tools";
|
|
31
29
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
32
|
-
const OMIT_FORM_ITEM_AND_DOM_KEYS = ['format', 'toISOString', 'toCSTString', 'switchValue', 'precision', 'clearNotShow', 'dependNames', 'shouldCellUpdate' // 表格内部性能优化属性,不应传递给 Form.Item
|
|
33
|
-
];
|
|
34
30
|
const RenderField = ({
|
|
35
31
|
text: value,
|
|
36
32
|
record,
|
|
@@ -65,7 +61,7 @@ const RenderField = ({
|
|
|
65
61
|
const {
|
|
66
62
|
mode,
|
|
67
63
|
cellName,
|
|
68
|
-
_isEditing,
|
|
64
|
+
_isEditing: isEditing,
|
|
69
65
|
form,
|
|
70
66
|
setState,
|
|
71
67
|
name,
|
|
@@ -80,13 +76,13 @@ const RenderField = ({
|
|
|
80
76
|
getIsNew,
|
|
81
77
|
shouldUpdateDebounce
|
|
82
78
|
} = config;
|
|
83
|
-
let
|
|
84
|
-
let
|
|
85
|
-
let
|
|
86
|
-
let
|
|
87
|
-
let
|
|
88
|
-
let
|
|
89
|
-
let
|
|
79
|
+
let lastFieldProps = fieldProps || {};
|
|
80
|
+
let lastRules = rules || [];
|
|
81
|
+
let lastRequired = required;
|
|
82
|
+
let lastValueType = valueType;
|
|
83
|
+
let lastDisabled = false;
|
|
84
|
+
let lastDesensitization = desensitization || [];
|
|
85
|
+
let lastComponent = component || editRender;
|
|
90
86
|
const isSingleMode = mode === 'single';
|
|
91
87
|
|
|
92
88
|
// type类型 首字母转大写
|
|
@@ -130,16 +126,16 @@ const RenderField = ({
|
|
|
130
126
|
// required & rules & fieldProps & disabled & valueType 函数化处理
|
|
131
127
|
// 优先使用 hook 返回的值,fallback 到原始值
|
|
132
128
|
if (_isFunction(required)) {
|
|
133
|
-
|
|
129
|
+
lastRequired = dynamicProps.required ?? required(rowData, reactiveParams);
|
|
134
130
|
}
|
|
135
131
|
if (_isFunction(fieldProps)) {
|
|
136
|
-
|
|
132
|
+
lastFieldProps = dynamicProps.fieldProps ?? fieldProps(rowData, reactiveParams);
|
|
137
133
|
}
|
|
138
134
|
if (_isFunction(rules)) {
|
|
139
|
-
|
|
135
|
+
lastRules = dynamicProps.rules ?? rules(rowData, reactiveParams);
|
|
140
136
|
}
|
|
141
137
|
if (_isFunction(valueType)) {
|
|
142
|
-
|
|
138
|
+
lastValueType = dynamicProps.valueType ?? valueType(currentValue, rowData, {
|
|
143
139
|
index,
|
|
144
140
|
form,
|
|
145
141
|
namePath: [...namePath, index],
|
|
@@ -147,16 +143,16 @@ const RenderField = ({
|
|
|
147
143
|
});
|
|
148
144
|
}
|
|
149
145
|
if (_isFunction(desensitization)) {
|
|
150
|
-
|
|
146
|
+
lastDesensitization = dynamicProps.desensitization ?? desensitization(rowData, reactiveParams);
|
|
151
147
|
}
|
|
152
148
|
|
|
153
149
|
// 获取最终的disabled
|
|
154
|
-
|
|
150
|
+
lastDisabled = getDisabled({
|
|
155
151
|
globalControl: otherProps?.globalControl,
|
|
156
152
|
formDisabled: otherProps?.formDisabled,
|
|
157
153
|
column,
|
|
158
154
|
tabledDisabled: config?.disabled,
|
|
159
|
-
columnFieldProps:
|
|
155
|
+
columnFieldProps: lastFieldProps,
|
|
160
156
|
params: rowParams
|
|
161
157
|
});
|
|
162
158
|
|
|
@@ -166,26 +162,28 @@ const RenderField = ({
|
|
|
166
162
|
}
|
|
167
163
|
|
|
168
164
|
// component 处理 - 优先使用 hook 返回的值
|
|
169
|
-
if (_isFunction(
|
|
170
|
-
|
|
165
|
+
if (_isFunction(lastComponent)) {
|
|
166
|
+
lastComponent = dynamicProps.component ?? lastComponent(rowData, reactiveParams);
|
|
171
167
|
}
|
|
172
168
|
|
|
173
|
-
// 更新
|
|
174
|
-
const
|
|
169
|
+
// 更新 lastEditRender 为处理后的 lastComponent
|
|
170
|
+
const lastEditRender = lastComponent;
|
|
175
171
|
|
|
176
172
|
// 是否只读文本
|
|
177
|
-
const isView = !isEditable || record?.['is-view'] || config.isView || virtualKey && !
|
|
173
|
+
const isView = !isEditable || record?.['is-view'] || config.isView || virtualKey && !isEditing || getDisabled({
|
|
178
174
|
globalControl: otherProps?.globalControl,
|
|
179
175
|
formDisabled: otherProps?.formDisabled,
|
|
180
176
|
column,
|
|
181
177
|
tabledDisabled: config?.disabled,
|
|
182
|
-
columnFieldProps:
|
|
178
|
+
columnFieldProps: lastFieldProps,
|
|
183
179
|
params: rowParams,
|
|
184
180
|
rowDisabled: rowDisabled || 'empty'
|
|
185
181
|
});
|
|
186
182
|
|
|
187
183
|
// 只读文本时,采用当前formItem的name,单行编辑时,使用生成的虚拟的name
|
|
188
184
|
const baseName = isView ? name : namePath;
|
|
185
|
+
|
|
186
|
+
// 多态:可能是内置组件类型、自定义 component,或已渲染的 ReactElement(lastEditRender),保留显式 any
|
|
189
187
|
let TargetComponent;
|
|
190
188
|
|
|
191
189
|
// 将Hooks调用移到组件顶层
|
|
@@ -196,18 +194,18 @@ const RenderField = ({
|
|
|
196
194
|
names,
|
|
197
195
|
label: label,
|
|
198
196
|
labelRequired,
|
|
199
|
-
required:
|
|
200
|
-
rules:
|
|
197
|
+
required: lastRequired,
|
|
198
|
+
rules: lastRules,
|
|
201
199
|
isSelect: isSelect({
|
|
202
|
-
dataSource:
|
|
200
|
+
dataSource: lastFieldProps?.dataSource,
|
|
203
201
|
type
|
|
204
202
|
}),
|
|
205
203
|
type
|
|
206
204
|
});
|
|
207
205
|
|
|
208
|
-
// 分离form item参数,防止对于参数透传(如onChange,防止重复触发)并优先级高于
|
|
206
|
+
// 分离form item参数,防止对于参数透传(如onChange,防止重复触发)并优先级高于 lastFieldProps 内部参数
|
|
209
207
|
const formItemChildProps = {
|
|
210
|
-
...
|
|
208
|
+
...lastFieldProps
|
|
211
209
|
};
|
|
212
210
|
|
|
213
211
|
// 使用useMemo优化defaultProps计算
|
|
@@ -219,7 +217,7 @@ const RenderField = ({
|
|
|
219
217
|
}), [name, formNamePath, cellName, column?.type, column?.fieldProps]);
|
|
220
218
|
|
|
221
219
|
// 允许formItem的属性放在column最外层 - 使用useMemo优化(剔除会透传到 DOM 的字段)
|
|
222
|
-
const
|
|
220
|
+
const lastFormItemProps = useMemo(() => ({
|
|
223
221
|
...defaultProps,
|
|
224
222
|
..._omit(resetProps, OMIT_FORM_ITEM_AND_DOM_KEYS),
|
|
225
223
|
...internalRule,
|
|
@@ -230,7 +228,7 @@ const RenderField = ({
|
|
|
230
228
|
// 当这些函数类型存在时,自动添加 shouldUpdate
|
|
231
229
|
// 因为这些函数依赖行数据,当行数据变化时需要重新计算
|
|
232
230
|
// 扩展到所有模式(single/multiple/cell),统一行为
|
|
233
|
-
// 注意:需要检查原始的 component/editRender,而不是处理后的
|
|
231
|
+
// 注意:需要检查原始的 component/editRender,而不是处理后的 lastComponent
|
|
234
232
|
const hasFunctionDependency = _isFunction(column?.disabled) ||
|
|
235
233
|
// disabled 是函数
|
|
236
234
|
_isFunction(fieldProps) ||
|
|
@@ -251,7 +249,7 @@ const RenderField = ({
|
|
|
251
249
|
// 性能优化已通过 useShouldUpdateForTable hook 的缓存和防抖机制实现
|
|
252
250
|
if (hasFunctionDependency) {
|
|
253
251
|
// 使用 shouldUpdate 监听同一行的数据变化;shouldUpdate 与 dependencies 互斥,始终优先 shouldUpdate
|
|
254
|
-
|
|
252
|
+
lastFormItemProps.shouldUpdate = (prevValues, currentValues) => {
|
|
255
253
|
const prevRow = _get(prevValues, [...namePath, index]);
|
|
256
254
|
const currentRow = _get(currentValues, [...namePath, index]);
|
|
257
255
|
// 如果行数据发生变化,则重新渲染
|
|
@@ -259,8 +257,8 @@ const RenderField = ({
|
|
|
259
257
|
};
|
|
260
258
|
}
|
|
261
259
|
if (['Switch', 'SwitchCheckbox'].includes(type)) {
|
|
262
|
-
|
|
263
|
-
|
|
260
|
+
lastFormItemProps.valuePropName = 'checked';
|
|
261
|
+
lastValueType = 'switch';
|
|
264
262
|
}
|
|
265
263
|
|
|
266
264
|
/**
|
|
@@ -269,11 +267,11 @@ const RenderField = ({
|
|
|
269
267
|
*/
|
|
270
268
|
const defaultTransform = useCallback(() => {
|
|
271
269
|
const types = ['DatePicker', 'RangePicker'];
|
|
272
|
-
if (!
|
|
273
|
-
return transformMap?.[type]?.(
|
|
270
|
+
if (!lastValueType && types.includes(type)) {
|
|
271
|
+
return transformMap?.[type]?.(lastFieldProps || {});
|
|
274
272
|
}
|
|
275
273
|
return {};
|
|
276
|
-
}, [
|
|
274
|
+
}, [lastValueType, type, lastFieldProps]);
|
|
277
275
|
|
|
278
276
|
/**
|
|
279
277
|
* 配置valueType时,基于formItem的normalize与getValueProps进行值类型转换
|
|
@@ -282,14 +280,15 @@ const RenderField = ({
|
|
|
282
280
|
const valueTypeTransform = useCallback(() => {
|
|
283
281
|
// SwitchCheckbox默认YN, 兼容已有组件
|
|
284
282
|
if (type === 'SwitchCheckbox') {
|
|
285
|
-
|
|
283
|
+
lastValueType = 'switch';
|
|
286
284
|
}
|
|
287
285
|
const params = {
|
|
288
286
|
...column,
|
|
289
|
-
mode:
|
|
287
|
+
mode: lastFieldProps?.mode
|
|
290
288
|
};
|
|
291
|
-
|
|
292
|
-
|
|
289
|
+
const valueTypeKey = lastValueType;
|
|
290
|
+
return _isFunction(valueTypeMap[valueTypeKey]) ? valueTypeMap[valueTypeKey](params) : {};
|
|
291
|
+
}, [type, lastValueType, column, lastFieldProps?.mode]);
|
|
293
292
|
if (names?.length) {
|
|
294
293
|
// 支持names配置,临时生成对应的formItem,用来存储单个对应的值
|
|
295
294
|
names = names.map(key => {
|
|
@@ -318,22 +317,23 @@ const RenderField = ({
|
|
|
318
317
|
}
|
|
319
318
|
const namesStr = [...baseName, index, dataIndex];
|
|
320
319
|
return transformNames({
|
|
321
|
-
...
|
|
320
|
+
...lastFormItemProps,
|
|
322
321
|
...valueTypeTransform()
|
|
323
322
|
}, form, names, namesStr, type);
|
|
324
|
-
}, [names, baseName, index, dataIndex,
|
|
325
|
-
if (!
|
|
323
|
+
}, [names, baseName, index, dataIndex, lastFormItemProps, type]);
|
|
324
|
+
if (!lastEditRender && typeof type === 'string') {
|
|
325
|
+
// componentMap 为内置组件命名空间,按字符串 type 动态取用,保留显式 any 索引
|
|
326
326
|
TargetComponent = componentMap[type] ?? /*#__PURE__*/_jsx(_Fragment, {});
|
|
327
327
|
}
|
|
328
|
-
if (isEditable &&
|
|
329
|
-
//
|
|
330
|
-
// 如果原本是函数,此时
|
|
331
|
-
// 如果原本是 ReactElement,
|
|
332
|
-
if ( /*#__PURE__*/React.isValidElement(
|
|
333
|
-
TargetComponent =
|
|
334
|
-
} else if (
|
|
328
|
+
if (isEditable && isEditing) {
|
|
329
|
+
// lastEditRender 已经是处理后的值(通过 dynamicProps.component 或直接计算)
|
|
330
|
+
// 如果原本是函数,此时 lastEditRender 已经是执行后的 ReactNode
|
|
331
|
+
// 如果原本是 ReactElement,lastEditRender 就是 ReactElement
|
|
332
|
+
if ( /*#__PURE__*/React.isValidElement(lastEditRender)) {
|
|
333
|
+
TargetComponent = lastEditRender;
|
|
334
|
+
} else if (lastEditRender) {
|
|
335
335
|
// 其他情况(可能是字符串或其他类型的 ReactNode)
|
|
336
|
-
TargetComponent =
|
|
336
|
+
TargetComponent = lastEditRender;
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
339
|
|
|
@@ -398,9 +398,9 @@ const RenderField = ({
|
|
|
398
398
|
const debounceRef = useRef(null);
|
|
399
399
|
|
|
400
400
|
// 使用 useCallback 创建稳定的 onChange 函数
|
|
401
|
-
const
|
|
401
|
+
const handleChange = useCallback(async (...args) => {
|
|
402
402
|
const executeChange = async (...innerArgs) => {
|
|
403
|
-
let
|
|
403
|
+
let callArgs = [...innerArgs];
|
|
404
404
|
const rowPath = [...namePath, index];
|
|
405
405
|
if (!onFieldChange && !onChange) {
|
|
406
406
|
if (dependencies?.length) {
|
|
@@ -409,15 +409,15 @@ const RenderField = ({
|
|
|
409
409
|
form.validateFields(validateFieldKeys);
|
|
410
410
|
}, 100);
|
|
411
411
|
}
|
|
412
|
-
return
|
|
412
|
+
return;
|
|
413
413
|
}
|
|
414
414
|
const row = form.getFieldValue(rowPath, true);
|
|
415
415
|
const orgRow = _cloneDeep(row);
|
|
416
416
|
if (onFieldChange) {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
TargetComponent?.props?.onFieldChange && (await TargetComponent.props.onFieldChange(...
|
|
420
|
-
onFieldChange && (await onFieldChange(...
|
|
417
|
+
callArgs = formatArgs(innerArgs);
|
|
418
|
+
callArgs[1] = row;
|
|
419
|
+
TargetComponent?.props?.onFieldChange && (await TargetComponent.props.onFieldChange(...callArgs));
|
|
420
|
+
onFieldChange && (await onFieldChange(...callArgs));
|
|
421
421
|
|
|
422
422
|
// onFieldChange 内已通过 form.setFieldValue(子路径) 或原地改 record 更新 store;此处再整行 setFieldValue(rowPath, rowAfter) 易用滞后快照覆盖 Field 刚写入的新值(如 formType)。仅延后读表做校验与 forceUpdate,不再整行回写。
|
|
423
423
|
setTimeout(() => {
|
|
@@ -442,9 +442,9 @@ const RenderField = ({
|
|
|
442
442
|
}
|
|
443
443
|
}, 0);
|
|
444
444
|
} else {
|
|
445
|
-
|
|
446
|
-
TargetComponent?.props?.onChange && (await TargetComponent.props.onChange(...
|
|
447
|
-
onChange && (await onChange(...
|
|
445
|
+
callArgs = callArgs.concat([row, index, form]);
|
|
446
|
+
TargetComponent?.props?.onChange && (await TargetComponent.props.onChange(...callArgs));
|
|
447
|
+
onChange && (await onChange(...callArgs));
|
|
448
448
|
const rowAfter = row;
|
|
449
449
|
form.setFieldValue(rowPath, rowAfter);
|
|
450
450
|
if (validateTrigger && validateTrigger.includes('onChange')) {
|
|
@@ -483,18 +483,18 @@ const RenderField = ({
|
|
|
483
483
|
};
|
|
484
484
|
}, []);
|
|
485
485
|
|
|
486
|
-
// 使用useCallback优化
|
|
487
|
-
const
|
|
486
|
+
// 使用useCallback优化handleBlur函数
|
|
487
|
+
const handleBlur = useCallback(async (...args) => {
|
|
488
488
|
if (!onBlur) {
|
|
489
|
-
return
|
|
489
|
+
return;
|
|
490
490
|
}
|
|
491
|
-
let
|
|
491
|
+
let callArgs = formatArgs(...args);
|
|
492
492
|
const rowPath = [...namePath, index];
|
|
493
493
|
const row = form.getFieldValue(rowPath, true);
|
|
494
494
|
const orgRow = _cloneDeep(row);
|
|
495
|
-
|
|
496
|
-
TargetComponent?.props?.onBlur && (await TargetComponent.props.onBlur(...
|
|
497
|
-
onBlur && (await onBlur(...
|
|
495
|
+
callArgs[1] = row;
|
|
496
|
+
TargetComponent?.props?.onBlur && (await TargetComponent.props.onBlur(...callArgs));
|
|
497
|
+
onBlur && (await onBlur(...callArgs));
|
|
498
498
|
// 判断属性是否变动
|
|
499
499
|
form.setFieldValue(rowPath, row);
|
|
500
500
|
if (validateTrigger && validateTrigger.includes('onBlur')) {
|
|
@@ -520,15 +520,15 @@ const RenderField = ({
|
|
|
520
520
|
let componentProps = useMemo(() => ({
|
|
521
521
|
form,
|
|
522
522
|
name: cellName,
|
|
523
|
-
...
|
|
523
|
+
...lastFieldProps,
|
|
524
524
|
...TargetComponent?.props,
|
|
525
525
|
namePath: [...namePath, index],
|
|
526
|
-
disabled:
|
|
527
|
-
onChange:
|
|
528
|
-
onBlur:
|
|
526
|
+
disabled: lastDisabled,
|
|
527
|
+
onChange: handleChange,
|
|
528
|
+
onBlur: handleBlur,
|
|
529
529
|
index,
|
|
530
530
|
confirm,
|
|
531
|
-
desensitization:
|
|
531
|
+
desensitization: lastDesensitization,
|
|
532
532
|
otherProps: {
|
|
533
533
|
form,
|
|
534
534
|
names,
|
|
@@ -537,15 +537,15 @@ const RenderField = ({
|
|
|
537
537
|
listName: cellName,
|
|
538
538
|
// 用于下拉框去重消费,保持和formlist一致
|
|
539
539
|
viewEmpty,
|
|
540
|
-
valueType:
|
|
540
|
+
valueType: lastValueType,
|
|
541
541
|
isView,
|
|
542
542
|
desensitizationKey: otherProps?.desensitizationKey,
|
|
543
543
|
source: 'ProEditTable'
|
|
544
544
|
}
|
|
545
|
-
}), [cellName,
|
|
545
|
+
}), [cellName, lastFieldProps, TargetComponent?.props, namePath, index, lastDisabled, handleChange, handleBlur, confirm, lastDesensitization, names, originalName, viewEmpty, lastValueType, isView, otherProps?.desensitizationKey]);
|
|
546
546
|
componentProps = _omit(componentProps, ['onFieldChange', 'namePath', 'index', ...OMIT_FORM_ITEM_AND_DOM_KEYS]);
|
|
547
547
|
if (['Switch', 'SwitchCheckbox'].includes(type)) {
|
|
548
|
-
|
|
548
|
+
lastFormItemProps.valuePropName = 'checked';
|
|
549
549
|
}
|
|
550
550
|
|
|
551
551
|
// 可编辑表格默认关闭scrollFollowParent
|
|
@@ -560,9 +560,9 @@ const RenderField = ({
|
|
|
560
560
|
const trimProps = isTrim(type, trim, proConfig); // 使用顶层调用的proConfig
|
|
561
561
|
|
|
562
562
|
const transformNormalize = namesTransformProps?.normalize ?? defaultTransformProps?.normalize;
|
|
563
|
-
const userNormalize =
|
|
563
|
+
const userNormalize = lastFormItemProps?.normalize;
|
|
564
564
|
const transformGetValueProps = namesTransformProps?.getValueProps ?? defaultTransformProps?.getValueProps;
|
|
565
|
-
const userGetValueProps =
|
|
565
|
+
const userGetValueProps = lastFormItemProps?.getValueProps;
|
|
566
566
|
const finalNormalize = transformNormalize && userNormalize ? (value, prevValue, allValues, isDiffMode) => {
|
|
567
567
|
// 用户 normalize 需要拿到组件原始值(如 DatePicker 的 dayjs)
|
|
568
568
|
const userValue = userNormalize(value, prevValue, allValues, isDiffMode);
|
|
@@ -583,203 +583,205 @@ const RenderField = ({
|
|
|
583
583
|
};
|
|
584
584
|
} : userGetValueProps || transformGetValueProps;
|
|
585
585
|
return {
|
|
586
|
-
...
|
|
586
|
+
...lastFormItemProps,
|
|
587
587
|
...defaultTransformProps,
|
|
588
588
|
...namesTransformProps,
|
|
589
589
|
...trimProps,
|
|
590
590
|
normalize: finalNormalize,
|
|
591
591
|
getValueProps: finalGetValueProps
|
|
592
592
|
};
|
|
593
|
-
}, [
|
|
593
|
+
}, [lastFormItemProps, defaultTransform, namesTransform, type, trim, proConfig]);
|
|
594
594
|
|
|
595
595
|
// rules 的 isView 过滤已移至 getFieldItem 内处理(支持 shouldUpdate 模式下的动态 isEditable)
|
|
596
596
|
|
|
597
|
-
const
|
|
597
|
+
const cellClassName = useMemo(() => classNames({
|
|
598
598
|
[className]: className
|
|
599
599
|
}), [className]);
|
|
600
600
|
|
|
601
|
-
//
|
|
602
|
-
const
|
|
603
|
-
//
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
if (shouldUpdateMode) {
|
|
612
|
-
// 重新获取最新的行数据(shouldUpdate 触发时,通过 getFieldValue 拿到最新值)
|
|
613
|
-
const latestRowData = form.getFieldValue([...namePath, index]) || record || {};
|
|
614
|
-
const latestReactiveParams = {
|
|
615
|
-
form,
|
|
616
|
-
index,
|
|
617
|
-
namePath: [...namePath, index]
|
|
618
|
-
};
|
|
619
|
-
const latestRowParams = [latestRowData, latestReactiveParams];
|
|
601
|
+
// shouldUpdate 模式下重新获取最新行数据并重算所有响应式属性,返回最新渲染状态(不修改外层闭包)
|
|
602
|
+
const recalcShouldUpdateState = () => {
|
|
603
|
+
// 重新获取最新的行数据(shouldUpdate 触发时,通过 getFieldValue 拿到最新值)
|
|
604
|
+
const latestRowData = form.getFieldValue([...namePath, index]) || record || {};
|
|
605
|
+
const latestReactiveParams = {
|
|
606
|
+
form,
|
|
607
|
+
index,
|
|
608
|
+
namePath: [...namePath, index]
|
|
609
|
+
};
|
|
610
|
+
const latestRowParams = [latestRowData, latestReactiveParams];
|
|
620
611
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
612
|
+
// ⭐ 关键修改:shouldUpdate 模式下,跳过缓存,直接重新计算所有响应式属性
|
|
613
|
+
let latestFieldProps = fieldProps || {};
|
|
614
|
+
if (_isFunction(fieldProps)) {
|
|
615
|
+
latestFieldProps = fieldProps(latestRowData, latestReactiveParams);
|
|
616
|
+
}
|
|
626
617
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
618
|
+
// 重新计算 required(用于可能的后续逻辑)
|
|
619
|
+
let latestRequired = required;
|
|
620
|
+
if (_isFunction(required)) {
|
|
621
|
+
latestRequired = required(latestRowData, latestReactiveParams);
|
|
622
|
+
}
|
|
632
623
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
624
|
+
// 重新计算 rules(用于可能的后续逻辑)
|
|
625
|
+
let latestRules = rules;
|
|
626
|
+
if (_isFunction(rules)) {
|
|
627
|
+
latestRules = rules(latestRowData, latestReactiveParams);
|
|
628
|
+
}
|
|
638
629
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
630
|
+
// 重新计算 desensitization
|
|
631
|
+
let latestDesensitization = desensitization || [];
|
|
632
|
+
if (_isFunction(desensitization)) {
|
|
633
|
+
latestDesensitization = desensitization(latestRowData, latestReactiveParams);
|
|
634
|
+
}
|
|
643
635
|
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
636
|
+
// 重新计算 component
|
|
637
|
+
let latestComponent = component || editRender;
|
|
638
|
+
if (_isFunction(latestComponent)) {
|
|
639
|
+
latestComponent = latestComponent(latestRowData, latestReactiveParams);
|
|
640
|
+
}
|
|
649
641
|
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
642
|
+
// 重新计算 isEditable(使用原始的 column.isEditable,而不是处理后的 isEditable)
|
|
643
|
+
let latestIsEditable = column.isEditable ?? true;
|
|
644
|
+
if (_isFunction(column.isEditable)) {
|
|
645
|
+
latestIsEditable = column.isEditable(latestRowData, latestReactiveParams);
|
|
646
|
+
}
|
|
655
647
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
648
|
+
// 重新计算 disabled
|
|
649
|
+
const latestDisabled = getDisabled({
|
|
650
|
+
globalControl: otherProps?.globalControl,
|
|
651
|
+
formDisabled: otherProps?.formDisabled,
|
|
652
|
+
column,
|
|
653
|
+
tabledDisabled: config?.disabled,
|
|
654
|
+
columnFieldProps: latestFieldProps,
|
|
655
|
+
params: latestRowParams
|
|
656
|
+
});
|
|
661
657
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
658
|
+
// 更新 componentProps 中的所有响应式属性
|
|
659
|
+
// latestTargetComponent 稍后计算,此处先占位;最终会在下方合并 latestTargetComponent?.props
|
|
660
|
+
let latestComponentProps = {
|
|
661
|
+
...componentProps,
|
|
662
|
+
...latestFieldProps,
|
|
663
|
+
disabled: latestDisabled,
|
|
664
|
+
desensitization: latestDesensitization,
|
|
665
|
+
// shouldUpdate 模式下,确保事件包装函数不被 fieldProps 覆盖
|
|
666
|
+
onChange: handleChange,
|
|
667
|
+
onBlur: handleBlur
|
|
668
|
+
};
|
|
671
669
|
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
...componentProps,
|
|
676
|
-
...latestFieldProps,
|
|
677
|
-
disabled: latestDisabled,
|
|
678
|
-
desensitization: latestDesensitization,
|
|
679
|
-
// shouldUpdate 模式下,确保事件包装函数不被 fieldProps 覆盖
|
|
680
|
-
onChange: _onChange,
|
|
681
|
-
onBlur: _onblur
|
|
682
|
-
};
|
|
670
|
+
// ⭐ 关键修改:在 shouldUpdate 模式下,需要重新设置 TargetComponent
|
|
671
|
+
// 因为 component 函数可能返回不同的结果
|
|
672
|
+
let latestTargetComponent = TargetComponent;
|
|
683
673
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
674
|
+
// 首先检查是否有内置type
|
|
675
|
+
if (!latestComponent && typeof type === 'string') {
|
|
676
|
+
latestTargetComponent = componentMap[type] ?? /*#__PURE__*/_jsx(_Fragment, {});
|
|
677
|
+
}
|
|
687
678
|
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
679
|
+
// 然后处理自定义 component
|
|
680
|
+
const latestIsView = !latestIsEditable || record?.['is-view'] || config.isView || virtualKey && !isEditing || getDisabled({
|
|
681
|
+
globalControl: otherProps?.globalControl,
|
|
682
|
+
formDisabled: otherProps?.formDisabled,
|
|
683
|
+
column,
|
|
684
|
+
tabledDisabled: config?.disabled,
|
|
685
|
+
columnFieldProps: latestFieldProps,
|
|
686
|
+
params: latestRowParams,
|
|
687
|
+
rowDisabled: rowDisabled || 'empty'
|
|
688
|
+
});
|
|
689
|
+
if (latestIsEditable && isEditing) {
|
|
690
|
+
if ( /*#__PURE__*/React.isValidElement(latestComponent)) {
|
|
691
|
+
latestTargetComponent = latestComponent;
|
|
692
|
+
} else if (latestComponent) {
|
|
693
|
+
latestTargetComponent = latestComponent;
|
|
691
694
|
}
|
|
695
|
+
}
|
|
692
696
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
});
|
|
703
|
-
if (latestIsEditable && _isEditing) {
|
|
704
|
-
if ( /*#__PURE__*/React.isValidElement(latestComponent)) {
|
|
705
|
-
latestTargetComponent = latestComponent;
|
|
706
|
-
} else if (latestComponent) {
|
|
707
|
-
latestTargetComponent = latestComponent;
|
|
708
|
-
}
|
|
697
|
+
// 查看模式
|
|
698
|
+
if (latestIsView) {
|
|
699
|
+
if (typeof viewRender === 'function') {
|
|
700
|
+
const latestCurrentValue = dataIndex ? latestRowData?.[dataIndex] : null;
|
|
701
|
+
const View = viewRender(latestCurrentValue, latestRowData || {}, options);
|
|
702
|
+
latestTargetComponent = /*#__PURE__*/_jsx(Container, {
|
|
703
|
+
viewEmpty: viewEmpty,
|
|
704
|
+
children: View
|
|
705
|
+
});
|
|
709
706
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
if (latestIsView) {
|
|
713
|
-
if (typeof viewRender === 'function') {
|
|
714
|
-
const latestCurrentValue = dataIndex ? latestRowData?.[dataIndex] : null;
|
|
715
|
-
const View = viewRender(latestCurrentValue, latestRowData || {}, options);
|
|
716
|
-
latestTargetComponent = /*#__PURE__*/_jsx(Container, {
|
|
717
|
-
viewEmpty: viewEmpty,
|
|
718
|
-
children: View
|
|
719
|
-
});
|
|
720
|
-
}
|
|
721
|
-
if ( /*#__PURE__*/React.isValidElement(viewRender)) {
|
|
722
|
-
latestTargetComponent = viewRender;
|
|
723
|
-
}
|
|
707
|
+
if ( /*#__PURE__*/React.isValidElement(viewRender)) {
|
|
708
|
+
latestTargetComponent = viewRender;
|
|
724
709
|
}
|
|
710
|
+
}
|
|
725
711
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
isView: latestIsView
|
|
735
|
-
}
|
|
736
|
-
};
|
|
712
|
+
// shouldUpdate 触发时外层 componentProps.otherProps.isView 是旧快照,需用最新值覆盖
|
|
713
|
+
latestComponentProps = {
|
|
714
|
+
...latestComponentProps,
|
|
715
|
+
otherProps: {
|
|
716
|
+
...latestComponentProps.otherProps,
|
|
717
|
+
isView: latestIsView
|
|
718
|
+
}
|
|
719
|
+
};
|
|
737
720
|
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
}
|
|
721
|
+
// componentProps 里展开了外层旧 TargetComponent?.props(如 { formType: "Input" }),
|
|
722
|
+
// 用 latestTargetComponent?.props 覆盖,确保不会被旧 cloneElement props 污染
|
|
723
|
+
if ( /*#__PURE__*/React.isValidElement(latestTargetComponent)) {
|
|
724
|
+
const elementProps = latestTargetComponent.props;
|
|
725
|
+
// 确保 props 是对象类型才进行展开
|
|
726
|
+
if (elementProps && typeof elementProps === 'object') {
|
|
727
|
+
latestComponentProps = {
|
|
728
|
+
...latestComponentProps,
|
|
729
|
+
...elementProps,
|
|
730
|
+
// 始终保证事件处理函数不被覆盖
|
|
731
|
+
onChange: handleChange,
|
|
732
|
+
onBlur: handleBlur
|
|
733
|
+
};
|
|
752
734
|
}
|
|
753
735
|
}
|
|
736
|
+
return {
|
|
737
|
+
finalComponentProps: latestComponentProps,
|
|
738
|
+
targetComponent: latestTargetComponent,
|
|
739
|
+
latestIsView,
|
|
740
|
+
effectiveRequired: latestRequired,
|
|
741
|
+
effectiveRules: latestRules,
|
|
742
|
+
effectiveFieldProps: latestFieldProps
|
|
743
|
+
};
|
|
744
|
+
};
|
|
754
745
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
746
|
+
// 根据 latestIsView 和最新 required/rules 构建正确的 Form.Item props
|
|
747
|
+
// 解决 shouldUpdate 触发时外层 finalFormItemProps 是旧闭包(rules 基于旧 isView 计算)的问题
|
|
748
|
+
const buildActiveFormItemProps = ({
|
|
749
|
+
latestIsView,
|
|
750
|
+
shouldUpdateMode,
|
|
751
|
+
effectiveRequired,
|
|
752
|
+
effectiveRules,
|
|
753
|
+
effectiveFieldProps
|
|
754
|
+
}) => {
|
|
758
755
|
if (latestIsView) {
|
|
759
756
|
// 查看模式:移除 rules 不做校验
|
|
760
|
-
|
|
761
|
-
}
|
|
757
|
+
return _omit(finalFormItemProps, ['rules']);
|
|
758
|
+
}
|
|
759
|
+
if (shouldUpdateMode) {
|
|
762
760
|
// shouldUpdate 模式下 finalFormItemProps 是旧闭包,需用最新 effectiveRequired/effectiveRules 重建 rules
|
|
763
761
|
const activeRules = Array.isArray(effectiveRules) ? [...effectiveRules] : [];
|
|
764
762
|
const hasRequiredRule = activeRules.some(r => r?.required === true);
|
|
765
763
|
if (effectiveRequired && !hasRequiredRule) {
|
|
766
|
-
const
|
|
764
|
+
const isSelectVal = isSelect({
|
|
767
765
|
dataSource: effectiveFieldProps?.dataSource,
|
|
768
766
|
type
|
|
769
767
|
});
|
|
770
768
|
activeRules.push({
|
|
771
769
|
required: true,
|
|
772
|
-
message: `${
|
|
770
|
+
message: `${isSelectVal ? locale.ProForm.selectPlaceHolder : locale.ProForm.inputPlaceholder}${label || ''}`
|
|
773
771
|
});
|
|
774
772
|
}
|
|
775
|
-
|
|
773
|
+
return {
|
|
776
774
|
...finalFormItemProps,
|
|
777
775
|
rules: activeRules.length > 0 ? activeRules : [{
|
|
778
776
|
required: false
|
|
779
777
|
}]
|
|
780
778
|
};
|
|
781
779
|
}
|
|
782
|
-
|
|
780
|
+
return finalFormItemProps;
|
|
781
|
+
};
|
|
782
|
+
|
|
783
|
+
// 组装字段组件:DOM 透传字段过滤、克隆/创建目标元素、原始值对比包裹(ListChangedWrapper)、确认弹窗包裹(ConfirmWrapper)
|
|
784
|
+
const assembleFieldComponent = finalComponentProps => {
|
|
783
785
|
// 当 viewRender 存在时,需要排除 finalComponentProps 中的 children,避免覆盖 Container 的 children
|
|
784
786
|
let propsForTarget = isView && typeof viewRender === 'function' ? _omit(finalComponentProps, ['children']) : finalComponentProps;
|
|
785
787
|
// 当目标为原生 DOM 元素(如 viewRender 返回 <div>)时,剔除 disabled、toCSTString 等,避免 React 警告
|
|
@@ -810,8 +812,8 @@ const RenderField = ({
|
|
|
810
812
|
form: form,
|
|
811
813
|
onDiff: onDiff,
|
|
812
814
|
type: type,
|
|
813
|
-
onChange:
|
|
814
|
-
onBlur:
|
|
815
|
+
onChange: handleChange,
|
|
816
|
+
onBlur: handleBlur,
|
|
815
817
|
valuePropName: finalFormItemProps.valuePropName,
|
|
816
818
|
normalize: finalFormItemProps.normalize,
|
|
817
819
|
getValueProps: finalFormItemProps.getValueProps,
|
|
@@ -827,11 +829,42 @@ const RenderField = ({
|
|
|
827
829
|
children: FieldComponent
|
|
828
830
|
});
|
|
829
831
|
}
|
|
830
|
-
|
|
832
|
+
return FieldComponent;
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
// 使用useCallback优化getFieldItem函数
|
|
836
|
+
const getFieldItem = (shouldUpdateMode = false) => {
|
|
837
|
+
// 如果处于 shouldUpdate 模式,需要重新获取最新的行数据并重新计算依赖值
|
|
838
|
+
let finalComponentProps = componentProps;
|
|
839
|
+
// shouldUpdate 模式下会被更新为最新值,供外层 FieldProvider 消费
|
|
840
|
+
let latestIsView = isView;
|
|
841
|
+
// 用于在 shouldUpdate 模式下重建正确的 Form.Item rules(外层 finalFormItemProps 是旧闭包)
|
|
842
|
+
let effectiveRequired = lastRequired;
|
|
843
|
+
let effectiveRules = lastRules;
|
|
844
|
+
let effectiveFieldProps = lastFieldProps;
|
|
845
|
+
if (shouldUpdateMode) {
|
|
846
|
+
const recomputed = recalcShouldUpdateState();
|
|
847
|
+
finalComponentProps = recomputed.finalComponentProps;
|
|
848
|
+
// shouldUpdate 模式下用重算结果覆盖外层 TargetComponent,供下方组装逻辑消费
|
|
849
|
+
TargetComponent = recomputed.targetComponent;
|
|
850
|
+
latestIsView = recomputed.latestIsView;
|
|
851
|
+
effectiveRequired = recomputed.effectiveRequired;
|
|
852
|
+
effectiveRules = recomputed.effectiveRules;
|
|
853
|
+
effectiveFieldProps = recomputed.effectiveFieldProps;
|
|
854
|
+
}
|
|
855
|
+
const activeFinalFormItemProps = buildActiveFormItemProps({
|
|
856
|
+
latestIsView,
|
|
857
|
+
shouldUpdateMode,
|
|
858
|
+
effectiveRequired,
|
|
859
|
+
effectiveRules,
|
|
860
|
+
effectiveFieldProps
|
|
861
|
+
});
|
|
862
|
+
const FieldComponent = assembleFieldComponent(finalComponentProps);
|
|
863
|
+
let FormItem = TargetComponent ? /*#__PURE__*/_jsx(Form.Item, {
|
|
831
864
|
validateFirst: true,
|
|
832
|
-
..._omit(activeFinalFormItemProps, ['render', 'key', 'width', 'hiddenNames', 'name', 'onCell', 'disabled',
|
|
865
|
+
..._omit(activeFinalFormItemProps, ['render', 'key', 'width', 'hiddenNames', 'name', 'onCell', 'disabled', lastFormItemProps.shouldUpdate ? 'shouldUpdate' : null]),
|
|
833
866
|
// 移除非必要字段,但保留 dependencies
|
|
834
|
-
className:
|
|
867
|
+
className: cellClassName,
|
|
835
868
|
name: formNamePath ? cellName.slice(formNamePath?.length - 1) : cellName,
|
|
836
869
|
children: FieldComponent
|
|
837
870
|
}) : /*#__PURE__*/_jsx(Container, {
|
|
@@ -875,132 +908,4 @@ const RenderField = ({
|
|
|
875
908
|
})
|
|
876
909
|
});
|
|
877
910
|
};
|
|
878
|
-
export default /*#__PURE__*/memo(RenderField,
|
|
879
|
-
// 自定义比较函数,只有关键props变化时才重新渲染
|
|
880
|
-
const {
|
|
881
|
-
text: prevText,
|
|
882
|
-
record: prevRecord,
|
|
883
|
-
index: prevIndex,
|
|
884
|
-
column: prevColumn,
|
|
885
|
-
config: prevConfig
|
|
886
|
-
} = prevProps;
|
|
887
|
-
const {
|
|
888
|
-
text: nextText,
|
|
889
|
-
record: nextRecord,
|
|
890
|
-
index: nextIndex,
|
|
891
|
-
column: nextColumn,
|
|
892
|
-
config: nextConfig
|
|
893
|
-
} = nextProps;
|
|
894
|
-
|
|
895
|
-
// 函数型动态属性(component/editRender/fieldProps/rules/required/disabled/isEditable/valueType)
|
|
896
|
-
// 可能依赖行内兄弟字段;行对象为同引用(原地修改)时,浅比较无法区分,需强制重渲染
|
|
897
|
-
const hasFunctionDependency = _isFunction(prevColumn?.component) || _isFunction(prevColumn?.editRender) || _isFunction(prevColumn?.fieldProps) || _isFunction(prevColumn?.rules) || _isFunction(prevColumn?.required) || _isFunction(prevColumn?.disabled) || _isFunction(prevColumn?.isEditable) || _isFunction(prevColumn?.valueType) || _isFunction(nextColumn?.component) || _isFunction(nextColumn?.editRender) || _isFunction(nextColumn?.fieldProps) || _isFunction(nextColumn?.rules) || _isFunction(nextColumn?.required) || _isFunction(nextColumn?.disabled) || _isFunction(nextColumn?.isEditable) || _isFunction(nextColumn?.valueType);
|
|
898
|
-
if (hasFunctionDependency && prevRecord === nextRecord) {
|
|
899
|
-
return false;
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
// 构建新的参数格式(与 ProForm 保持一致)
|
|
903
|
-
const prevNamePath = getNamePath(prevConfig?.name, prevConfig?.virtualKey);
|
|
904
|
-
const nextNamePath = getNamePath(nextConfig?.name, nextConfig?.virtualKey);
|
|
905
|
-
const prevReactiveParams = {
|
|
906
|
-
form: prevConfig?.form,
|
|
907
|
-
index: prevIndex,
|
|
908
|
-
namePath: [...prevNamePath, prevIndex]
|
|
909
|
-
};
|
|
910
|
-
const nextReactiveParams = {
|
|
911
|
-
form: nextConfig?.form,
|
|
912
|
-
index: nextIndex,
|
|
913
|
-
namePath: [...nextNamePath, nextIndex]
|
|
914
|
-
};
|
|
915
|
-
const prevRowParams = [prevRecord, prevReactiveParams];
|
|
916
|
-
const nextRowParams = [nextRecord, nextReactiveParams];
|
|
917
|
-
if (_isFunction(prevColumn?.disabled) && _isFunction(nextColumn?.disabled)) {
|
|
918
|
-
if (prevColumn?.disabled(prevRecord, prevReactiveParams) !== nextColumn?.disabled(nextRecord, nextReactiveParams)) {
|
|
919
|
-
return false;
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
// fieldProps 函数化直接更新,无法比对返回值是否一致
|
|
924
|
-
// 优化:不直接调用函数,而是比较输入参数(record 和 reactiveParams)
|
|
925
|
-
// 如果输入参数相同,fieldProps 的返回值应该相同(纯函数假设)
|
|
926
|
-
if (_isFunction(prevColumn?.fieldProps) && _isFunction(nextColumn?.fieldProps)) {
|
|
927
|
-
// 比较 record 数据是否变化
|
|
928
|
-
if (!_isEqualWith(prevRecord, nextRecord, customEqualForFunction)) {
|
|
929
|
-
return false;
|
|
930
|
-
}
|
|
931
|
-
// reactiveParams 中的 form、index、namePath 已经在外层比较过了,无需重复比较
|
|
932
|
-
}
|
|
933
|
-
// fieldProps 为对象时,必须比较配置变化(如 dataSource 异步更新)
|
|
934
|
-
if (!_isFunction(prevColumn?.fieldProps) && !_isFunction(nextColumn?.fieldProps)) {
|
|
935
|
-
const isFieldPropsEqual = _isEqualWith(prevColumn?.fieldProps, nextColumn?.fieldProps, customEqualForFunction);
|
|
936
|
-
if (!isFieldPropsEqual) {
|
|
937
|
-
return false;
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
// 通用函数比较方法
|
|
942
|
-
// 优化:不直接调用函数,而是比较函数引用和输入参数
|
|
943
|
-
const compareFunctionResult = (prevColumn, nextColumn, prevValues, nextValues, prevReactiveParams, nextReactiveParams, functionName) => {
|
|
944
|
-
const prevFunc = prevColumn?.[functionName];
|
|
945
|
-
const nextFunc = nextColumn?.[functionName];
|
|
946
|
-
if (_isFunction(prevFunc) && _isFunction(nextFunc)) {
|
|
947
|
-
// 函数引用变化说明闭包可能捕获了新的外部状态(如异步加载的 list),必须重渲染
|
|
948
|
-
if (prevFunc !== nextFunc) return false;
|
|
949
|
-
// 同引用函数,比较输入参数(纯函数假设:输入相同则输出相同)
|
|
950
|
-
return _isEqualWith(prevValues, nextValues, customEqualForFunction);
|
|
951
|
-
}
|
|
952
|
-
return true; // 如果不是函数或只有一个是函数,认为相等
|
|
953
|
-
};
|
|
954
|
-
|
|
955
|
-
// 使用简化后的比较逻辑
|
|
956
|
-
const functionFields = ['rules', 'component', 'desensitization', 'isEditable', 'required'];
|
|
957
|
-
if (functionFields.some(field => !compareFunctionResult(prevColumn, nextColumn, prevRecord, nextRecord, prevReactiveParams, nextReactiveParams, field))) {
|
|
958
|
-
return false;
|
|
959
|
-
}
|
|
960
|
-
|
|
961
|
-
// 基本props比较
|
|
962
|
-
if (!_isEqual(prevText, nextText) || prevIndex !== nextIndex) {
|
|
963
|
-
return false;
|
|
964
|
-
}
|
|
965
|
-
|
|
966
|
-
// 记录关键字段比较(避免完整对象比较的性能开销)
|
|
967
|
-
if (prevRecord?.rowKey !== nextRecord?.rowKey || prevRecord?._addFlag !== nextRecord?._addFlag) {
|
|
968
|
-
return false;
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
// 列配置比较(只比较关键字段),required,disabled为函数时,需要重新计算
|
|
972
|
-
if (prevColumn?.dataIndex !== nextColumn?.dataIndex || prevColumn?.type !== nextColumn?.type || prevColumn?.name !== nextColumn?.name) {
|
|
973
|
-
return false;
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
// config中关键字段比较
|
|
977
|
-
if (prevConfig?._isEditing !== nextConfig?._isEditing || prevConfig?.mode !== nextConfig?.mode) {
|
|
978
|
-
return false;
|
|
979
|
-
}
|
|
980
|
-
|
|
981
|
-
// 当前单元格的值比较
|
|
982
|
-
const prevDataIndex = prevColumn?.dataIndex;
|
|
983
|
-
const nextDataIndex = nextColumn?.dataIndex;
|
|
984
|
-
if (prevDataIndex && nextDataIndex && prevDataIndex === nextDataIndex) {
|
|
985
|
-
if (prevRecord?.[prevDataIndex] !== nextRecord?.[nextDataIndex]) {
|
|
986
|
-
return false;
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
|
|
990
|
-
// 特殊处理:当使用自定义 component 函数时,比较整个 record 对象
|
|
991
|
-
// 因为自定义组件可能依赖 record 中的其他字段(不只是当前列的 dataIndex)
|
|
992
|
-
if (_isFunction(prevColumn?.component) || _isFunction(nextColumn?.component)) {
|
|
993
|
-
// 浅比较 record 的所有属性
|
|
994
|
-
const prevKeys = Object.keys(prevRecord || {});
|
|
995
|
-
const nextKeys = Object.keys(nextRecord || {});
|
|
996
|
-
if (prevKeys.length !== nextKeys.length) {
|
|
997
|
-
return false;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// 使用 some 方法代替 for 循环
|
|
1001
|
-
if (prevKeys.some(key => prevRecord?.[key] !== nextRecord?.[key])) {
|
|
1002
|
-
return false;
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
return true;
|
|
1006
|
-
});
|
|
911
|
+
export default /*#__PURE__*/memo(RenderField, arePropsEqual);
|