
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
form-presenter
Advanced tools
FormPresenter 使用指南
FormPresenter 是一个根据数据模型生成表单的对象(MDD)的库
所有表单场景
git clone https://github.com/zlx362211854/form-presenter.git
cd form-presenter
npm i
npm run dev
npm i form-presenter
实例化 presenter
import FormPresenter from "form-presenter";
const presenter = new FormPresenter({}); // 实例化
实例化时设置表单数据模型
const presenter = new FormPresenter({
formItems: [
{
label: "姓名",
key: "name",
uiType: "input",
rules: [
{
required: true,
message: "请输入姓名",
},
],
},
],
});
// 设置一个name字段
设置表单的初始值
const presenter = new FormPresenter({
formItems: [
{
label: '姓名',
key: 'name',
uiType: 'input',
rules: [
{
required: true,
message: '请输入姓名',
},
],
},
],
initFormValues: {
name: 'zlx' // 设置name的初始值为zlx
}
})
// 在一些情景下,我们需要初始化presenter实例了以后再设置表单的初始值,这时可以在表单组件实例中将初始值作为props传入
const presenter = new FormPresenter({
formItems: [
{
label: '姓名',
key: 'name',
uiType: 'input', // 设置字段的ui组件为input
rules: [
{
required: true,
message: '请输入姓名',
},
],
},
],
initFormValues: {} // 实例化时不设置初始值,而是在表单组件中设置
})
// 获取表单组件实例
const FormComponent = presenter.getFormComponent()
// 设置初始值
<FormComponent
initFormValues={{
name: 'zlx' // 设置name的初始值为zlx
}}
/>
获取表单组件实例并渲染
// 获取表单组件实例
const FormComponent = presenter.getFormComponent()
// 渲染实例
<FormComponent {...formComponentProps}/>
代码示例
import FormPresenter from "./FormPresenter";
import { IFormItem } from "./declare";
const info: IFormItem[] = [
{
label: "姓名",
key: "name",
uiType: "input", // 设置字段的ui组件为input
rules: [
{
required: true,
message: "请输入姓名",
},
],
},
];
export default class Test extends React.Component {
private presenter: FormPresenter;
constructor(props) {
super(props);
this.presenter = new FormPresenter({
formItems: info,
initFormValues: {},
});
}
render() {
const FormComponent = this.presenter.getFormComponent();
const formComponentProps = {
initFormValues: {
name: "zlx",
},
};
return (
<div title={"测试"}>
<FormComponent {...formComponentProps} />
</div>
);
}
}
生成组件效果:

某些情景下,我们需要在多个表单字段之间联动,如:姓名输入为“杨超越”时,年龄自动变为 18,我们可以通过监听 onValuesChange 来实现
const info: IFormItem[] = [
{
label: '姓名',
key: 'name',
uiType: 'input', // 设置字段的ui组件为input
rules: [
{
required: true,
message: '请输入姓名',
},
],
},
{
label: '年龄',
key: 'age',
uiType: 'input',
rules: [
{
required: true,
message: '请输入年龄',
},
],
},
]
// ...
constructor(props) {
super(props)
this.presenter = new FormPresenter({
formItems: info,
initFormValues: {},
onValuesChange: ({form}, changedvalues, allValues) => {
// reaction
if (changedvalues && changedvalues.name) {
if (changedvalues.name === "杨超越") {
form.setFields({
age: {
value: 18
},
})
}
}
},
})
}
某些情景下,presenter 内置的表单元素并不能满足个性化需求,这时可以通过自定义渲染来动态添加自定义表单组件
const info: IFormItem[] = [
{
label: "姓名",
key: "name",
uiType: "input", // 设置字段的ui组件为input
rules: [
{
required: true,
message: "请输入姓名",
},
],
},
];
export default class Test extends React.Component {
private presenter: FormPresenter;
constructor(props) {
super(props);
this.presenter = new FormPresenter({
formItems: info,
initFormValues: {},
});
}
add = () => {
this.presenter.addFormItem({
label: "描述",
key: "desc",
uiType: "custom", // 添加类型为自定义组件(也可以添加内置组件)
rules: [
{
required: false,
message: "",
},
],
render: this.renderDom,
});
};
renderDom = React.forwardRef((props, ref) => {
return <span ref={ref}>这是添加的自定义组件</span>;
});
render() {
const FormComponent = this.presenter.getFormComponent();
const formComponentProps = {
initFormValues: {
name: "zlx",
},
};
return (
<div title={"测试"}>
<FormComponent {...formComponentProps} />
<Button onClick={() => this.add()}>添加一个自定义组件</Button>
</div>
);
}
}

presenter 生命周期
presenter 默认提供三个生命周期:

presenter 默认提供提交按钮,有时候需要自定义提交按钮,屏蔽提交按钮只需传入:
this.presenter = new FormPresenter({
formItems: info,
initFormValues: {},
disableSubmitButton: true, // 屏蔽提交按钮
});
组件布局
默认提供两种布局
grid

flow

grid 布局可以指定每个字段所占的空间:
this.presenter = new FormPresenter({
formItems: info,
initFormValues: {},
formLayout: {
type: "grid",
col: 8, // 每个field占据8个栅格(总共24)
},
});
表单默认布局为 flow 布局
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| formItems | 指定用于渲染 form 的数据 | FormItem[] | 是 | |
| initFormValues | 初始化表单的值 | Object | 是 | |
| wrapperClassName | 表单包围元素的 className | string | 否 | |
| loading | 显示表单的加载状态 | boolean | false | 否 |
| disableSubmitButton | 不展示默认表单提交按钮 | boolean | false | 否 |
| formLayout | 表单的布局 | IformLayout | 'flow' | 否 |
| onFormCreated | 表单实例被创建的生命周期 | Function | 否 | |
| onFormMount | 表单组件被加载的生命周期 | Function | 否 | |
| onFormDestroy | 表单组件被销毁的生命周期 | Function | 否 | |
| onFieldsChange | 表单组件 field 改变的回调 | Function | 否 | |
| onValuesChange | 表单组件 field 的值改变的回调 | Function | 否 |
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| label | 字段的 label | string | 是 | |
| Key | 字段在 form 中的唯一的 key | string | 是 | |
| uiType | 字段的 ui 类型 | uiTypeEnums | 否 | |
| rules | 字段的校验规则 | boolean | false | 否 |
| selectOptions | select 下拉类型的 option | IOptions | ||
| radioOptions | radioradio 类型的 option | IOptions | ||
| min | input number 类型的最小值 | number | ||
| max | input number 类型的最大值 | number | ||
| prefix | input number 类型的前缀 | string | ||
| suffix | input number 类型的后缀 | string | ||
| step | input number 类型的小数点后位数 | number | string | ||
| disabled | 是否禁用 | boolean | false | |
| showTime | datePicker & dateRangePicker 是否可选择时间 | boolean | false | |
| format | datePicker & dateRangePicker & timePicker 时间展示格式 | string | ||
| uploadProps | 上传组件的参数 | IuploadProps | ||
| extra | field 的额外注释 | string | Function | ||
| divider | 是否渲染横隔线 | Boolean |
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| key | options 的 key | string | 是 | |
| Title | options 的 title | string | 是 |
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| action | 上传文件的地址 | string | 否 | |
| maxFileLength | 上传的最大文件数量 | number | 否 | |
| fileTypes | 上传文件的类型 | Array | 否 | |
| fileSize | 单个文件上传的限制大小 单位:MB | number | 2 | 否 |
| 参数 | 说明 | 类型 | 默认值 | 必填 |
|---|---|---|---|---|
| type | 布局类型 | string,可选‘grid’和‘flow’ | flow | 否 |
| Col | 当 type 为 grid 时,每个 grid 占据的空间 | number | 8(总共 24) | 否 |
| labelCol | 当布局为 flow 时,字段 label 占据的空间 | object | {span: 6} | 否 |
| wrapperCol | 当布局为 flow 时,字段值占据的空间 | object | {span: 14} | 否 |
| 可选值 | 说明 |
|---|---|
| text | 文字 |
| Info | 文字 |
| Input | 输入框 |
| numberInput | 数字输入框 |
| currencyInput | 货币输入框 |
| switch | 开关 |
| select | 下拉框 |
| Radio | 单选框 |
| datePicker | 日期选择 |
| dateRangePicker | 日期范围选择 |
| monthPicker | 月份选择 |
| timePicker | 时间选择 |
| upload | 上传 |
| avatar | 头像 | 图片上传 |
| picturesWall | 图片墙 |
| custom | 自定义渲染 |
getFormComponent 获取 form 组件实例
const presenter = new FormPresenter<IFormProps>({
formItems: refundFormItems
})
render() {
const FormComponent = presenter.getFormComponent()
return (
<FormComponent/>
)
}
getForm 返回 form 实例
const presenter = new FormPresenter<IFormProps>({
formItems: refundFormItems
})
submit() {
// 在表单提交的时候做校验
const form = presenter.getForm()
form.validateFields((err, values) => {
if (!err) {
console.log('Form返回的值为:', values)
}
})
}
addFormItem 动态增加一个 form 的字段
const presenter = new FormPresenter<IFormProps>({
formItems: refundFormItems
})
componentDidMount() {
// 动态增加一个input类型的字段
presenter.addFormItem({
label: '身高',
key: 'high',
uiType: 'input', // 添加类型为input
rules: [
{
required: false,
message: '',
},
]
}, 0) // 添加为第一个字段
// 动态增加一个自定义渲染的字段
presenter.addFormItem({
label: '描述',
key: 'desc',
uiType: 'custom', // 添加类型为自定义组件
rules: [
{
required: false,
message: '',
},
],
render: () => <span>自定义渲染的字段</span>,
}, 2) // 添加为第三个字段
}
hasField 判断表单是否含有某字段
this.presenter.hasField("name"); // true
getFormItems 获取表单全部字段配置
this.presenter.getFormItems();
updateFormItem 更新某字段
this.presenter.updateFormItem({
key: "name",
label: "更新--姓名",
uiType: "input",
});
resetFields 把 form 重置回初始值的状态
this.presenter.resetFields();
FormPresenter 是基于 ant design Form 封装的,基于模型驱动的组件,可满足日常大部分表单组件的快速开发,是模型驱动 MDD 模式下一种表单解决方案。
FAQs
FormPresenter
The npm package form-presenter receives a total of 3 weekly downloads. As such, form-presenter popularity was classified as not popular.
We found that form-presenter demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.