前言
做前端的几年间,陆续接过几个外包,基本都是不需要ui设计的表单页面。虽然开发起来不难但也繁琐,所以想做一个工具能减少部分重复的工作。
介绍文档
使用地址
简介
基于 antd 的低代码表单生成器,旨在快速搭建简单的表单应用场景。
设计模式
表单模式
服务
我使用了axios进行接口请求,配置时可以自定义axios拦截器并预览请求结果。
事件
事件分为表单事件和组件事件,目前仅有一些常用的事件,后续有需求会慢慢添加。支持设置防抖节流、串联功能,串联是指需要等待当前事件执行完成后再往下执行后续事件。
本地部署
在使用地址中点击下载按钮可以下载一个表单模板,根据介绍文档设置schema即可部署到服务器。
也可以作为组件在本地使用,添加自定义组件应对一些复杂场景。
环境准备
确保正确安装 Node.js 且版本为 18+ 。
安装依赖
yarn add @roddan/form-editor
代码编写
表单设计模式代码如下:
import React, { useRef } from 'react';
import {
FormEditor,
Material,
Settings,
FormCanvas,
} from '@roddan/form-editor';
const Editor = () => {
const ref = useRef();
return (
<FormEditor
mode="design"
ref={ref}
// 预览打开的url和保存回调
actionProp={{
// 预览url
previewUrl: `xxxxx`,
// 保存按钮回调
onSave(schema) {
console.log('schema');
console.log(schema);
},
// 下载按钮回调,不传不展示按钮
download(schema) {
console.log('schema');
console.log(schema);
},
}}
>
<Material />
<FormCanvas />
<Settings />
</FormEditor>
);
};
export default Editor;
设置页点击保存按钮后会将 schema 存在 localstorage 中,预览页会从中取。
预览模式其实就是最终要拿到的表单页。
import React from 'react';
import { FormEditor, FormCanvas } from '@roddan/form-editor';
const Editor = () => {
const ref = useRef();
return (
<FormEditor
mode="form"
// 这里不传会从localstorage中取
defaultValue={schema}
>
<FormCanvas />
</FormEditor>
);
};
export default Editor;
自定义组件
自定义组件参数及类型如下:
interface IDragElementProp {
type: string; // 组件类型
render: FC<any>; // 表单渲染组件
setting: FC<any>; // 属性设置组件
text: string; // 组件库文案
Icon: ReactNode; // 组件库icon
eventActions: EEventAction[]; // 支持的事件列表
initialData: Partial<IBaseElement>; // 初始默认值
}
以颜色选择器为例,配置事件-值变化同步其他组件,属性可设置弹框位置placement
import React from 'react';
import { SettingItem, SettingWrap, useRegisterEvents, EEventAction, useFormUpdate } from '@roddan/form-editor';
import type { IBaseElement, TElementRender, TElementSetting } from '@roddan/form-editor';
import { ColorPicker, Select } from 'antd';
const RenderContent: TElementRender = ({
element,
fieldValue = '',
customStyle, // 自定义css
setFieldValue,
}) => {
const { placement } = element;
const { eventFunctions } = useRegisterEvents(element);
// 监听值发生变化的hook
useFormUpdate(() => {
eventFunctions[EEventAction.VALUE_CHANGE]?.(fieldValue);
}, [fieldValue]);
return (
<ColorPicker
value={fieldValue}
onChange={(v) => {
setFieldValue(v.toHexString());
}}
placement={placement}
style={{ ...customStyle }}
/>
);
};
const SettingContent: TElementSetting = ({ element, setElementProp }) => {
const { placement } = element;
return (
<SettingWrap title="元素设置">
<SettingItem label="弹窗位置">
<Select
options={['left', 'right'].map((item) => ({
label: item,
value: item,
}))}
value={placement}
onChange={(val) => {
setElementProp('placement', val);
}}
/>
</SettingItem>
</SettingWrap>
);
};
const Icon = <div>icon-</div>;
const eventActions = [EEventAction.VALUE_CHANGE];
const initialData: Partial<IBaseElement> = {
elementName: '颜色选择器',
gridSpan: 3,
gridLayout: false,
placement: 'left',
};
const type = 'custom';
export const customElement = {
type,
render: RenderContent,
setting: SettingContent,
Icon,
text: '测试颜色组件121231231',
eventActions,
initialData,
};
在FormEditor组件上传入即可。
import React from 'react';
import { FormEditor, FormCanvas } from '@roddan/form-editor';
import { customElement } from './customEl';
const Comp = () => {
return (
<FormEditor
mode="design"
customElements={[customElement]}
>
<FormCanvas />
</FormEditor>
);
};
export default Comp;