legao-form
v0.0.14
Published
<p style="text-align: center"> <a href="https://www.npmjs.com/package/legao-form" target="blank"><img src="https://img12.360buyimg.com/imagetools/jfs/t1/116999/3/6618/21716/5ebcf703Ebfd265e2/4cc4be1aad9e30db.png" width="220" alt="legao-form Logo" /></a>
Downloads
8
Readme
Form 表单生成器,通过配置 FormData 即可生成可交互的 form 页面。
[TOC]
Usage
使用之前请先看说明文档,会让你节省百分之 80 的开发时间。
具体代码编写参考下方 demo。
详细介绍
FormItem 类型列表
- [x] group 分组列表
- [x] input 输入框
- [x] textarea 大文本框
- [x] select 下拉选择
- [x] async_select 异步下拉选择
- [x] radio 单选框
- [x] checkbox 复选框
- [x] date 日期
- [x] upload 文件上传
- [x] complex 多表单联动
- [x] 表示已经实现的表单项。
FormContainer
| 属性 | 类型 | 含义 | 是否必填 | 备注说明 |
| :------: | :------------------------------ | :--------------- | :------: | ------------------------------------------------------------------------ |
| data | array<FormData> | 表单项数据数组 | 是 | |
| isEdit | boolean | 表单整体模式 | 是 | true:编辑状态;false:只读状态 |
| submit | Func:(values, form)=>void | 表单提交回调 | 是 | |
| btnText | string | 表单提交按钮文本 | 是 | |
| children | Func:(param: Object)=>ReactNode | 表单提交按钮文本 | 是 | 参数对象类型: param:{errors, handleSubmit, isSubmitting, handleReset}
|
Group 属性配置
| 属性 | 类型 | 含义 | 是否必填 | 备注说明 | | :------: | :------ | :------------- | :------: | --------------------------------------------------- | | label | string | 表单项标题文本 | 是 | | | type | string | 表单类型 | 是 | 此项决定了表单项的展示类型 | | show | boolean | 是否显示 | - | | | grid | number | 栅格占位 | - | 页面分 24 份,整个 form item 所占宽度(包含 label) |
FormData 属性配置
| 属性 | 类型 | 含义 | 是否必填 | 备注说明 |
| :------: | :-------------- | :------------- | :------: | ---------------------------------------------------------------------------------------- |
| label | string | 表单项标题文本 | 是 | |
| name | string | 表单项 属性名 | 是 | 表单提交 name,同一个 form 中 name 不能重复 |
| type | string | 表单类型 | 是 | 此项决定了表单项的展示类型 |
| value | string | 表单项的值 | 是 | string
| checkbox
特殊为 array<string>
|
| show | boolean | 是否显示 | - | 该表单项是否显示 |
| readonly | string | 是否只读 | 是 | 该表单项是否只读 |
| grid | number | 栅格化布局 | - | 页面分 24 份,整个 form item 所占宽度(包含 label) |
| schema | string<yup> | 表单验证条件 | - | 表单验证条件,集成 yup 框架进行表单验证 |
| extra | object<Extra> | 表单项扩展属性 | - | 可对表单 label,表单元素单独控制,最终整个对象会透传给实际的表单元素,Extra
见下方说明 |
Extra 属性说明(不同属性,针对不同表单类型)
| 属性 | 类型 | 含义 | 是否必填 | 备注说明 |
| :---------: | :---------------------- | :--------------------- | :------: | ---------------------------------------------------------------------------------- |
| grid | number | 表单元素栅格占位 | - | 页面分 24 份,表单元素所占宽度(不包含 label) |
| labelgrid | number | 表单 label 栅格占位 | - | 页面分 24 份,表单 label 所占宽度 |
| placeholder | string | placeholder | - | 特指使用 input / textarea 时指定 placeholder
|
| options | array<OptionsObject> | 选项列表 | - | 特指使用 select / radio / checkbox 时指定 options
,OptionsObject
见下方说明 |
| action | string | 文件上传提交 action | - | 特指使用 upload 时指定 action
,文件上传目标地址 |
| callback | Func:(fileInfo:any)=>{} | 文件成功回调 | - | 特指使用 upload 时文件上传成功之后,对结果进行处理 |
| child | array<FormItem> | 复合表单联动子表单元素 | - | 特指使用 complex 时 显示的子表单元素 FormItem
即为上面所有的普通表单项 |
OptionsObject 属性说明
| 属性 | 类型 | 含义 | 是否必填 | 备注说明 | | :---: | :----- | :-------------- | :------: | -------- | | value | string | option 实际值 | 是 | | | label | string | option 显示文本 | 是 | |
表单验证
每个表单项都可以配置 schema
来设置表单校验,该功能使用的是 yup 工具,如有需要可参考 yup 文档。
- 特殊说明:每个表单配置表单校验,只需要在自己的数据结构中设置
schema
即可,嵌套表单同理设置嵌套的子表单校验即可。
特别说明(多表单项联动)
多表单项联动就是单个表单的嵌套。
具体示例
- demo 生成结果:
- demo 示例代码:
import React, { Component } from "react";
import { FormContainer, FormSchema } from "legao-form";
function timeout(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
const FormData = [
{
label: "普通表单项示例:",
type: "group",
show: false,
grid: 24,
},
{
label: "input1",
name: "inputName1",
value: "这个 input has value",
type: "input",
readonly: false,
grid: 12,
show: true,
schema: FormSchema.string().required(),
extra: {
grid: 18,
placeholder: "这个有value ,也有placeholder",
},
},
{
label: "input2",
name: "inputName2",
value: "",
type: "input",
readonly: true,
grid: 12,
show: true,
schema: FormSchema.string().required(),
extra: {
grid: 8,
placeholder: "这个没有value ,但是有placeholder",
},
},
{
label: "textarea",
name: "textareaName",
value: "",
type: "textarea",
show: true,
readonly: true,
grid: 24,
extra: {
grid: 18,
placeholder: "placeholder 还是要有的哦, 可以用 grid 控制宽度",
},
schema: FormSchema.string().required(),
},
{
label: "select",
name: "selectName",
value: "select1",
type: "select",
show: true,
readonly: true,
grid: 12,
extra: {
grid: 10,
options: [
{ value: "select1", label: "options1" },
{ value: "select2", label: "options2" },
{ value: "select3", label: "options3" },
],
},
schema: FormSchema.string().required(),
},
{
label: "async_select",
name: "asyncSelectName",
value: "",
type: "async_select",
readonly: true,
grid: 12,
extra: {
grid: 10,
loadOptions: async (input: string) => {
await timeout(500);
if (!input) {
return [
{ value: "asyncSelect1", label: "asyncOpt1" },
{ value: "asyncSelect2", label: "asyncOpt2" },
{ value: "asyncSelect3", label: "asyncOpt3" },
];
}
return [
{ value: "asyncSelect1", label: "asyncOpt1" },
{ value: "asyncSelect2", label: "asyncOpt2" },
{ value: "asyncSelect3", label: "asyncOpt3" },
].filter((item) => item.value.indexOf(input) > -1);
},
},
schema: FormSchema.string().required(),
},
{
label: "radio",
name: "radioName",
value: "radio2",
type: "radio",
show: true,
readonly: true,
grid: 12,
extra: {
options: [
{ value: "radio1", label: "radioVal1" },
{ value: "radio2", label: "radioVal2" },
{ value: "radio3", label: "radioVal3" },
],
},
schema: FormSchema.string().required(),
},
{
label: "checkbox",
name: "checkboxName",
value: ["checkbox1", "checkbox3"],
type: "checkbox",
show: true,
readonly: false,
grid: 12,
extra: {
grid: 14,
options: [
{ value: "checkbox1", label: "商详" },
{ value: "checkbox2", label: "搜索" },
{ value: "checkbox3", label: "推荐" },
{ value: "checkbox4", label: "广告" },
],
},
},
{
label: "Date",
name: "dateName",
value: "2020/01/02",
type: "date",
show: false,
readonly: true,
grid: 12,
extra: {
grid: 14,
},
schema: FormSchema.string().required().length(10),
},
{
label: "Upload",
name: "file",
type: "upload",
show: true,
readonly: true,
grid: 12,
extra: {
grid: 14,
action: "https://www.mocky.io/v2/5cc8019d300000980a055e76",
callback: async (fileInfoResult: any) => {
// callback 可以不传,不传就走 antd upload 默认处理逻辑
console.log(
"-----------130---------",
fileInfoResult.file.response.url
);
return fileInfoResult.file.response.url;
},
},
schema: FormSchema.string().required(),
},
{
label: "复合表单项示例:",
type: "group",
show: false,
grid: 24,
},
{
label: "就你们",
name: "complexName",
value: "",
type: "complex",
show: false,
readonly: true,
grid: 24,
extra: {
grid: 14,
child: [
{
label: "测试复合radio",
name: "complexName",
value: "1",
type: "radio",
show: false,
readonly: true,
grid: 24,
extra: {
grid: 14,
options: [
{ value: "1", label: "是" },
{ value: "0", label: "否" },
],
},
},
{
label: "测试 Checkbox",
name: "checkbox123",
value: ["1", "3"],
type: "checkbox",
show: "values.complexName.complexName==1",
readonly: false,
grid: 24,
extra: {
grid: 14,
options: [
{ value: "1", label: "商详" },
{ value: "2", label: "搜索" },
{ value: "3", label: "推荐" },
{ value: "4", label: "广告" },
],
},
},
],
},
schema: FormSchema.object({
complexName: FormSchema.string().required(),
}),
},
{
label: "还有谁",
name: "complexName2",
value: "",
type: "complex",
show: false,
readonly: true,
grid: 24,
extra: {
grid: 14,
child: [
{
label: "测试复合radio",
name: "complexRadio",
value: "1",
type: "radio",
show: false,
readonly: true,
grid: 24,
extra: {
grid: 14,
options: [
{ value: "1", label: "其他" },
{ value: "0", label: "没了" },
],
},
},
{
label: "",
name: "complexInput",
value: "",
type: "input",
show: "values.complexName2.complexRadio==1",
readonly: false,
grid: 24,
extra: {
grid: 14,
},
},
],
},
schema: FormSchema.object({
complexName: FormSchema.string().required(),
}),
},
{
label: "提交按钮:",
type: "group",
show: false,
grid: 24,
},
];
/**
* Form 表单生成器,示例代码
*/
class App extends Component {
state = {
checked: 1,
};
changeRadio = (val: number) => {
this.setState({
checked: val,
});
};
render() {
return (
<div>
<div className="appContainer">
<div className="radioDiv">
<input
type="radio"
id="huey"
name="drone"
value="1"
checked={this.state.checked === 1}
onChange={this.changeRadio.bind(this, 1)}
/>
<label htmlFor="huey">编辑</label>
</div>
<div className="radioDiv">
<input
type="radio"
id="dewey"
name="drone"
value="0"
checked={this.state.checked === 0}
onChange={this.changeRadio.bind(this, 0)}
/>
<label htmlFor="dewey">只读</label>
</div>
</div>
<FormContainer
data={FormData}
width="100%"
isEdit={this.state.checked === 1}
submit={(values, form) => {
console.log(values, "提交表单");
form.setSubmitting(false);
}}
btnText="提交"
>
{({ errors, handleSubmit, isSubmitting, handleReset }) => {
return (
<a
// disabled={isSubmitting}
onClick={() => {
handleSubmit();
}}
>
提交2
</a>
);
}}
</FormContainer>
</div>
);
}
}
export default App;
意见或建议
有任何建议可以提交 issues,或者给我们发邮件。