FormRender-简易小程序表单解决方案
背景
在 ToB 场景中,需要录入众多数据,一个表单字段可能数十个,如果每个字段都写一个jsx 组件来表示,那代码量会瞬间臃肿涨至一两千行,维护起来极其不方便。因此需要一个“表单生成器”,在提高代码复用性同时也能极大提高工作效率。 为此参考了XRender 后写了一个简易版本的 FormRender 组件,分享一下使用方法以及实现思路。
开始使用
demo 地址: github.com/hexianzhi/t…
最简使用 demo:
import { Button, View } from "@tarojs/components"; import React, { useRef, useState } from "react"; import FormRender from "../../compoments/formRender"; import "./index.scss"; const formData = [ { key: "a", title: "地址", type: "input", required: true, typeProps: { placeholder: "请输入", }, }, { key: "c", title: "国家", type: "picker", typeProps: { mode: "selector", range: ["美国", "中国", "巴西", "日本"], }, }, { key: "b", title: "备注", type: "textarea", }, ]; export default function (props) { const formRef = useRef<any>(); const [formValue, setformValue] = useState({}); const [formSchema, setformSchema] = useState(formData); const onChange = (newValue) => { setformValue(newValue); }; const onSubmit = () => { const isValid = formRef.current.validate(); console.log("isValid: ", isValid); }; return ( <View className="index"> <FormRender ref={formRef} formValue={formValue} formSchema={formSchema} onChange={onChange} ></FormRender> <Button onClick={onSubmit}>提交</Button> </View> ); }复制代码
效果图:
更多用法可以查看 complex.tsx
文件
基本使用思路
formSchema
描述表单信息,formValue
为表单值,这两个字段均由外部组件控制。
改变
formValue
:onChange改变
formSchema
:如果
formSchema
放在单独文件中,函数组件可以通过传递 setState 方法让回调调用,类组件一样但也可以通过绑定 this 的方式调用外部组件
setState
内部组件引起的改动:在
formSchema
中设置回调,回调中调用外部组件中的setState
。 如onColumnChange
校验可通过
validate
方法,validate
会通过校验formSchema
中定义的规则
formSchema 规范
具体说明可查看组件 type.d.ts 文件中的 IFormSchema
类型定义,以下为扩展说明
type
字段决定了使用哪个组件来渲染, 组件必须要在widgets
文件夹下声明并导出。required
和rules
字段用于做校验判断。rules
为对象数组,可书写多个校验规则。支持pattern
正则以及validate
函数形式,其中message
为提示信息。title
、diabled
、required
、hidden
字段支持布尔值以及函数形式。可在SupportFunctionItem
添加其他字段支持title
、diabled
、required
、hidden
字段会展开作为第一级字段注入到自定义组件中。可在injectCompKeys
添加其他字段支持typeProps
字段用于补充组件支持的更为细致的属性,可自行展开或者使用高阶组件withItemToProps
展开。render
为函数,配合type = custom
使用, 返回JSX
用于自定义组件。extra
用于在元素下展示更多说明信息任意其他字段会传递给自定义组件,可以根据需要自行魔改
如何扩展组件
先写好项目组件,然后在
widgets
文件夹下引入项目组件并注入value
等信息并导出即可,相关props
可查看IWidgetProps
接口schema
中的custom
函数中返回JSX
元素
重置样式应该统一在 index.scss
做
注意事项
组件使用
React.meomo
进行性能优化,因此在更改formSchema
中注意深克隆对象进行更改对象,如果直接更改formSchema
中的对象会导致对比函数中的 pre props 和 current props 一致,进而无法重新渲染 。(当然去掉 React.memo 也可以)
TODO
性能优化,组件独立渲染互不干扰
作者:歌顿与烈焰
链接:https://juejin.cn/post/7025878046624186399