字段继承
- github: github.com/easy-page/e…
- 文档站官网:easy-page.github.io/easy-page-d…
- 文档站 github: github.com/easy-page/e…
在表单开发中,我们会经常遇到这样的一个场景:
- 我想要之前的字段 A,但是又对它有一些调整。
此时,我们的做法可能是:
- 将差异的点抽象成:Props,在组件使用的地方,根据不同的场景传递不同的 Props。
但这样有个问题:
- 我们影响了原有的字段 A,那两个使用场景都需要回测。
- 我们需要做额外的抽象工作,增加开发成本。
- 抽象不一定完美,可能后续还会有所调整。
在 EasyPage
中,我们可通过:nodeUtil.extends
完美解决上述场景。一个字段,可变化的内容:
- 副作用
- 显隐逻辑
- 默认值、label、tooltip 等文案
- 组件 Props
- 数据处理
- 验证逻辑
我们的这个:nodeUtil.extends
包含了上述所有变化。
示例
在之前的例子中,我们继承过年龄字段,我们先来定义一个非常完整的年龄字段:
- 字段 ID: 'age'; 字段 Label: '年龄';字段默认值:'';字段必填:是。
- 字段提交时,处理成 number 类型,提交的 key 为:
age
- 字段增加校验:如未填写,则提示:“请输入年龄”;和
name
字段联动,当:name=pk
时,年龄可超过 200 岁,否则不可。 - 字段的 placeholder 根据:
name
的值而变化。 - 当字段
name=a
时,不展示年龄字段。 - 当字段
age < 10
岁时,增加提示语:“儿童”
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Empty, InputEffectedType, nodeUtil } from '@easy-page/antd-ui';
import React from 'react';
export const age = nodeUtil.createField<
string,
{ name: string },
Empty,
InputEffectedType
>(
'age',
'年龄',
{
/** 默认值 */
value: '',
/** 必填 * 号 */
required: true,
/** 数据预处理 */
postprocess(context) {
return {
age: Number(context.value),
};
},
/** 字段验证 */
validate({ value, pageState }) {
if (!value) {
return { success: false, errorMsg: '请输入年龄' };
}
if (+value < 0 || (+value > 200 && pageState.name !== 'pk')) {
return { success: false, errorMsg: '请输入合法年龄' };
}
return { success: true };
},
/** 字段副作用 */
actions: [
{
effectedKeys: ['name'],
/** 加载时,立即执行 */
initRun: true,
action: ({ effectedData }) => {
return {
effectResult: {
inputProps: {
placeholder: `${effectedData.name || '-'} 的年龄`,
},
},
};
},
},
],
/** 字段显示与隐藏 */
when: {
effectedKeys: ['name'],
show({ effectedData }) {
return effectedData.name !== 'a';
},
},
},
{
/** 输入框配置 */
input: { trigger: 'onChange' },
/** FormItem 配置 */
formItem: {
/** 自定义提示语:带上下文 */
customExtra: ({ value }) => {
return <div>{value && +value < 10 ? '儿童' : ''}</div>;
},
},
}
);
我们看一下效果:
见:easy-page.github.io/easy-page-d…
继承
基于上述的演示,我们来继承并替换掉这个年龄:
- 字段 ID: 'age'; 字段 Label: '我的年龄';字段必填:否。
- 验证时,允许为空
- 年龄字段永远展示。
- 给年龄字段增加一个问号提示文案
import { nodeUtil } from '@easy-page/antd-ui';
import { age } from './age';
export const newAge = nodeUtil.extends(age, {
name: '我的年龄',
required: false,
validate(oldValidate) {
return (options) => {
if (!options.value) {
return { success: true };
}
return oldValidate?.(options);
};
},
when(oldWhen) {
return {
effectedKeys: oldWhen?.effectedKeys || [],
show(context) {
return true;
},
};
},
/** 更改组件配置 **/
fieldUIConfig: (oldConfig) => {
const newConfig = { ...(oldConfig || {}) };
newConfig.formItem = newConfig.formItem || {};
newConfig.formItem.tooltip = '这是新的年龄';
return newConfig;
},
});
基于上述示例,我们通过:extends
扩展出自身所需要的新的年龄,而且对原有 age
无任何影响。
针对原有字段的属性:
- name、id、required 等属性直接变化即可。
- 对于函数类型属性,则都提供了:
oldXxx
来决定如何执行。
如:
validate(oldValidate) {
return (options) => {
if (!options.value) {
return { success: true };
}
return oldValidate?.(options);
};
},
返回了一个新的验证函数。
我们开看看效果: