前言

从4月份跳槽到这家公司已经2个月时间了,期望是将我封装的Schema表单,一体化表格放进公司的组件库中,在使用过程中去不断地优化和改进。没想到,新公司已经有了一套完整的Schema表单并且投入使用已经1年多了。那就把低代码的设计思路分享一下,望指正。

graph TD
Ui库选型 --> 设计JSON属性 --> 是否允许强制刷新 --> 渲染模式 --> 组件复用

Ui库选容器

相对于React来说,目前市面上嵌套函数最火的是Ui库非ant输入框怎么调大小d莫属容器对桌面的压强怎么算,在老东家的时候,由于项目启动较早,采用的ant嵌套结构d3,使用antd3来封装Schema表单会面临一个问题,表单一个值的更新会造成整个页面的重新渲染,这无疑对前端的性能是个巨大的灾容器所能容纳什么叫做容器的容积难。由于是自己封装,不考虑公司等其他客观因素,所以采用antd4作为基准的UI库,来进行二次封装。

设计JSON属性

设计JSON属性,首先数组的定义要保证json见名知意,JSON属性的复杂程JSON度取决是否要将不同场景都考虑到json解析,是否做到整体表单的细化使用场景。现在市面上的大规模表单使用场景,要么是栅格布局,要么是外层嵌套一些样式。如输入框的英文数组初始化外层嵌套样式,是否要整体的去控制外层的样式,是否允许开发自定义容器是什么设计这些样式。由于我封装嵌套表单的时候是有这一些场景的存在的。所以我设计了一套栅格布局样式,和开发可以自定义设计样式的属性。

qq输入框然最重要的还是自由度,因为你不能保证每个人都会花费时间去了解你实现的底层引擎逻辑,不能保证每个人都会去使用你已经封装容器苗的很好的API,所以要留出入口,至于一些使用问题,可以嵌套是什么意思在定期的代码评审中去讨论相关的事宜,也许会有更好的建议。

外层整体容器属性文档

不会还有人没手搓过低代码吧

内部单个组件的属性控制

对于内部单个组件来说,是否希望单个组件拥有表单的所有状态,是否可以所有的组件单独引用也可以达到容器设计使用最外层容器的效果,是要考虑到的。

对于单个组件来说,这些都是不可缺少的。

  • 校验规则肯定是不可容器技术缺少的一环
  • 每个json组件也应该拥有自己唯一的key值。
  • 回填值的能力
  • 单个json解析组件的属性管理
  • 具有数据源的组件要如何设计

不会还有人没手搓过低代码吧

是否允许强制刷新

对于整个组件的读值来说,整个数据源是一个对象数组,既然是对象,就可能存在更改对象中容器设计的某一属性值会造成不触发重新渲染的问题,更要考虑一次操作中是否会有多次的json格式怎么打开渲染操作,是否可以将这些操作合并,最后统一渲染,这些我们数组词可以通过React的一个Hook完美解决这个问题,并且赋予组件强制刷新的能力: useReduer

渲染模式

对于渲染来说嵌套分类汇总的操作步骤,不管是单个组件还是多个组件都应该去走一个自定义渲染逻辑的方案,这一部我参考了antd pr嵌套虚拟化o的Schema表单的设计理念,通过公容器中有某种酒精含量的酒精溶液共的方法,通过key值的判断,去生成不同的虚拟DOM嵌套是什么意思对应不同的组件,最后将这些组件统一放入一个数组中,在页面上去将这个数组循环展示出来。

export const createComponents = (item: SchemaFormItemType, formFn?: any) => {
  const { col, type } = item;
  const schemaComponents = () => {
    switch (type) {
      case 'Input': // 输入框
        return <InputItem item={item} />;
      case 'TextArea': // 文本域 内置字数
        return <TextAreaItem item={item} />;
      case 'Select': // 选择器
        return <SelectItem item={item} />;
      case 'Radio': // 单选框
        return <RadioItem item={item} />;
      case 'Checkbox': // 多选框
        return <CheckboxItem item={item} />;
      case 'DatePicker': // 日期选择器
        return <DatePickerItem item={item} />;
      case 'RangePicker': // 范围选择器
        return <RangePickerItem item={item} />;
      case 'Switch': // 开关
        return <SwitchItem item={item} />;
      case 'Slider': // 进度条
        return <SliderItem item={item} />;
      case 'InputNumber': // 数字输入框
        return <InputNumberItem item={item} />;
      case 'Rate': // 评价器
        return <RateItem item={item} />;
      case 'Cascader': // 级联选择器
        return <CascaderItem item={item} />;
      case 'barCharts': // 柱形图
        return <BarChartsItem item={item} />;
      case 'BarLineCharts': // 折线图
        return <BarLineCharts item={item} />;
      case 'CakeCharts': //饼图
        return <CakeChartsItem item={item} />;
      case 'FormTable': // 表单中简单表格
        return <FormTableItem item={item} />;
      case 'Title': // h1 标签
        return <h1 {...item.labelProps}>{item.labelName}</h1>;
      case 'Custom': // 自定义
        return <CustomItem item={item} />;
    }
  };
  return (
    <Col span={col ?? 24} key={item.labelValue}>
      {schemaComponents()}
    </Col>
  );
};

在封装初期我也考虑过是否将一些相似的组件放在同一个tsx文件中去渲染,为了后面方便数组初始化对单一组件的维护,最后将所有的组件都成为一个单独的个体进行构造

渲染过后

既然整个页面都可以使用整段的JSON对象去渲染,那么对于一些用户自定义表单或者用户自己构建表单的场景,我们就需要和服务端达成共识,将表单的整个data.d.ts类型文件发送给服务端,服务端简历相对应的DB来储存这些信息,当然我们发送的过程中,要尽可能地去减容器技术少我们发送的数据量,这个过程中,我们是需要去封装一个整体的转化方法来实现。

export const conversionJson = (data: any) => {
  const values = [...data];
  values.sort(sortArr('y'));
  // 根据W的值判断是否半行 1:半行 2整行
  const jsonData = values.map((i: any) => {
    return {
      ...i,
      col: i.w === 1 ? 12 : 24,
    };
  });
  return jsonData;
};

这里由于是我自己的尝试,我没有进行太过负责的逻嵌套是什么意思辑封装

效果图

容器数组的定义布局

不会还有人没手搓过低代码吧

自定义表单样式

不会还有人没手搓过低代码吧

可拖拽的表单设计器

不会还有人没手搓过低代码吧

后记

新公司技术栈不定,目前vue和React的项目同时跟进,同时自己也在看一些技术书籍。在这里记录一下自己封装低代码的思路。如果有同学有很好的设计思嵌套查询路,或者有一些推荐的书籍可以在下面评论出来。

一定要在自己毕业3年后可以成为一名合格的前端负责容器所能容纳什么叫做容器的容积