$ npm install schemant-form
一个基于 antd 的 schema form 方案,主要用于满足业务场景中用户需要自定义表单的需求,通过本方案可以快速上线 schema form 给用户定制使用。
本方案的特点是仅定义了单个控件的 schema,因此具有完全灵活的布局自定义能力。此外框架本身也内置了一组开箱即用的布局和自定义控件,用于简单需求的快速上线。
如果内置套件不满足要求,还可以通过框架提供的 util 快速定制布局和控件。
$ npm install schemant-form --save
import React from 'react';
import { SchemaForm } from 'schemant-form';
const schema = [
{
name: '节点属性',
controls: [
{
shape: 'Input',
name: 'id',
label: '节点 ID',
defaultValue: '',
value: 123,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'Input',
name: 'name',
label: '节点名称',
defaultValue: '',
value: 123,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'InputNumber',
name: 'x',
label: '位置: x',
defaultValue: '',
value: 123,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'InputNumber',
name: 'y',
label: '位置: y',
defaultValue: '',
value: 123,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'InputNumber',
name: 'width',
label: '大小: 宽度',
defaultValue: '',
value: 180,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'InputNumber',
name: 'height',
label: '大小: 高度',
defaultValue: '',
value: 30,
disabled: true,
required: false,
hidden: false,
},
{
shape: 'Datetime',
name: 'modifiedTime',
label: '修改时间',
defaultValue: '',
value: '',
disabled: true,
required: false,
hidden: false,
},
],
},
{
name: '节点配置',
controls: [
{
shape: 'Input',
name: 'param',
label: '节点参数',
defaultValue: '',
value: '',
disabled: false,
required: false,
hidden: false,
},
],
},
];
export default () => (
<div style={{ width: 300, minHeight: 500, border: '1px solid #d9d9d9' }}>
<SchemaForm schema={schema} onFieldsChange={console.log} />
</div>
);
除增加了 schema
属性外,其它属性完全与 antd 的 Form 保持一致。
interface ControlSchema {
shape: string; // 控件类型
name: string | number | (string | number)[]; // 控件名称
label: string; // 控件标签
defaultValue: string | number | boolean; // 默认值
value: string | number | boolean; // 当前值
disabled: boolean; // 是否禁用
required: boolean; // 是否必填
tooltip?: string; // 辅助说明
extra?: string; // 固定帮助文案
placeholder?: string; // placeholder
hidden: boolean; // 是否隐藏
options?: TOption[]; // 一般用于 select 组件的可选项
originData?: Record<string, any>; // 原始数据,可透传到控件
dependencies?: TDependency[]; // 依赖的字段
}
// src/components/schemant/select
import React from 'react';
import { Form, Select as ASelect } from 'antd';
import 'antd/es/select/style';
import {
ControlSchema,
FormItemWrapper,
renderFormItemExtra,
} from 'schemant-form';
interface Props {
controlSchema: ControlSchema;
}
export const Select: React.FC<Props> = props => {
const { controlSchema } = props;
const {
required,
tooltip,
extra,
name,
label,
placeholder,
options = [],
} = controlSchema;
return (
<FormItemWrapper schema={controlSchema}>
{({ hidden, disabled, initialValue }) => {
return (
<Form.Item
name={name}
label={label}
initialValue={initialValue}
tooltip={tooltip}
extra={renderFormItemExtra(extra)}
required={required}
hidden={hidden}
>
<ASelect disabled={disabled} placeholder={placeholder}>
{options.map(option => {
const { title, value } = option;
return (
<ASelect.Option key={value.toString()} value={value as any}>
{title}
</ASelect.Option>
);
})}
</ASelect>
</Form.Item>
);
}}
</FormItemWrapper>
);
};
// src/app.tsx
import { ControlMap } from 'schemant-form';
import { Select } from '@/components/schemant/select';
ControlMap.setComponent('select', Select);
如果默认的布局不符合需求,可以只使用 schemant-form 的控件联动和注册能力,Form 渲染层完全自定义。
具体的方式为:
import React from 'react';
import { Form } from 'antd';
import { FormInstance, FormProps } from 'antd/es/form';
import { ControlSchema, ControlMap } from 'schemant-form';
import 'antd/es/form/style';
type Schema = ControlSchema[];
interface Props extends FormProps {
schema: Schema;
form?: FormInstance;
}
export const CustomForm: React.FC<Props> = props => {
const { schema, form: formInstance, ...others } = props;
const [form] = Form.useForm(formInstance);
return (
<Form {...others}>
{schema.map(controlSchema => {
const { name, shape } = controlSchema;
const ControlComponent = ControlMap.getComponent(shape);
if (!ControlComponent) {
console.error('未找到对应的控件:', shape);
return null;
}
return (
<ControlComponent
key={name.toString()}
controlSchema={controlSchema}
/>
);
})}
</Form>
);
};
FormItemWrapper
util 定义自定义控件,即可快速获得具有联动能力的控件,如上方的自定义控件注册步骤© 2010 - cnpmjs.org x YWFE | Home | YWFE