• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

手撸一个拖拽式表单生成低代码工具leggo

相关文章 搞代码 3年前 (2022-04-21) 30次浏览 已收录 0个评论
文章目录[隐藏]
  • 演示地址:https://kerrycodes.github.io/
  • Github:https://github.com/KerryCodes…
  • 装置:npm i leggo

story

因为老员工的到职,我接手了一个齐全由表单组成的公布模块,之前我并没有看过业务源码。后续因为接入新的需要而冲进去保护这坨代码。留神我用了“坨”这个量词,你应该明确我在说什么。因为整个模块短少顶层设计,导致保护老本极高,频频报bug。于是开始思考为什么不能通过拖拽间接生成和保护这些表单呢?于是leggo就此诞生,名字来源于乐高Lego,寓意像搭积木一样实现表单的设计。

leggo哲学

  • 尽管利用了“拖拽”这一最直观简略的交互方式。但leggo并非面向非前端人员,leggo是一个为业余前端开发者晋升效率的工具
  • leggo从一开始就没有想要做成一个大而全的表单配置解决方案。 第一版甚至只是花了一个下午便告实现。所以leggo并不会为了可能实现简单逻辑的表单组件而放弃易用性。leggo真正要做的是帮忙前端开发疾速搭建和保护表单构造,轻松实现那些无脑反复搬砖的表单组件。这使得前端开发可能更专一于开发领有特定简单逻辑交互的表单组件。
  • leggo放弃了简直齐全凋谢的自在拓展空间。 岂但可拖拽的表单组件库可能被自在注册。所有通过leggo模板渲染的组件也能够轻松的被整体笼罩、组装或重写属性。你甚至能够裸露各种公共状态和函数给leggo生产。所以leggo并非只能利用于简略的表单设计场景,这齐全取决于开发者的大胆拓展。
  • 上手老本极低。 如果你相熟React和Antd,则你只须要学习1-2个leggo的Api就能够开始在我的项目中部署。Antd库中FormForm.Item以及相干input组件的所有属性和事件仍旧能够失常定义和应用。

根底利用

以下所有代码的外围就只是这一句const leggo= LeggoForm.useLeggo(schemaModel, middleware, publicStates),心愿不要有任何浏览累赘。

假如你曾经通过leggo表单设计器生成了一个表单模板(取得一个JSON对象,即下列代码中schemaModel),则仅通过以下2行代码你就失去了理论须要的表单:

<code class="typeScript">export const schemaModel= {
  //JSON
}
<code class="typeScript">export { LeggoForm } from 'leggo'
export { schemaModel } form './schemaModel'


function MyForm(){
  const leggo= LeggoForm.useLeggo(schemaModel)
  
  return <LeggoForm leggo={leggo} />
}

咱们从leggo导出了LeggoForm,而schemaModel是通过leggo表单设计器生成的JSON,LeggoForm这个高阶组件会将模版JSON解析并渲染成理论的表单组件。

从应用的角度来说LeggoForm和Antd中的Form简直没有任何差异(除了必须要挂载leggo这个属性)。你能够在LeggoForm上定义任何Form组件容许的属性并失常运行,比方像以下这样:

<code class="typeScript">function MyForm(){
  const leggo= LeggoForm.useLeggo(schemaModel)
  const [form]= Form.useForm()

  return (
    <LeggoForm leggo={leggo} 
      form={form} 
      labelCol={ span: 6 }
      wrapperCol={ span: 14 }
      onValuesChange={handleValuesChange} 
      onFinish={hanldeFinish} 
      .
      .
      .
    />
  )
}

思考到你的表单模板schemaModel可能不是存在本地,而须要从服务器异步近程拉取,则你能够这样部署:

<code class="typeScript">function MyForm(){
  const leggo= LeggoForm.useLeggo()
  const [form]= Form.useForm()
  
  useEffect(() => {
    leggo.resetSchemaModel(schemaModel)
  }, [schemaModel])

  return (
    <LeggoForm leggo={leggo} 
      form={form} 
      labelCol={ span: 6 }
      wrapperCol={ span: 14 }
      onValuesChange={handleValuesChange} 
      onFinish={hanldeFinish} 
      .
      .
      .
    />
  )
}

简略的表单通过以上代码曾经足够部署利用了。上面咱们逐渐引入更简单的场景。以下是咱们须要的一个表单组件,能够留神到在组件到右侧有一个“同步”按钮。这种个性化的组件并没有方法通过拖拽实现全副设计。

不要焦急,咱们先通过拖拽实现左侧经典表单组件局部的设计。右侧的按钮咱们只须要在渲染表单前通过中间件函数注入即可,中间件函数在leggo中是作为表单渲染前灵便拓展的伎俩之一。代码如下:

<code class="typeScript">import { TConfigs } from 'leggo/lib/interface';


function MyForm(){
  const leggo= LeggoForm.useLeggo(schemaModel, middleware)
  const [form]= Form.useForm()
  
  //  异步的状况
  //  useEffect(() => {
  //    leggo.resetSchemaModel(schemaModel, middleware)
  //  }, [schemaModel])

  return <LeggoForm leggo={leggo} />
}


// 定义一个中间件函数
function middleware(configs: TConfigs) {
  configs.Successor= (props: React.PropsWithChildren<any>) => (
    <div style={{display: 'flex'}}>
      { props.children }
      <Button>同步</Button>
    </div>
  )
}

值得注意的是,中间件函数只会在整个schemaModel注入时执行。无论表单后续如何更新和渲染,两头函数都不会运行(除非你又通过leggo.resetSchemaModel从新注入一个新的schemaModel)。所以你不须要放心由中间件函数可能导致的性能问题。

你会留神到leggo引擎在运行中间件函数时为其注入一个参数configs。这个对象十分重要,它来自schemaModel,你通过leggo表单设计器拖拽和设置的简直所有参数都存在这个对象中。实际上,咱们正是通过中间件函数在革新由表单设计器生成的schemaModelconfigs中有2个要害的属性itemPropsinputProps

itemProps

itemProps蕴含的参数有name、label、rules等。没错,这个对象会被间接注入进Form.Item组件:

<Form.Item {...itemProps} ></Form.Item>

inputProps

inputProps蕴含的参数有disabled、style、placeholder、htmlType等。这个对象会被间接注入进input相干组件:

<Input {...inputProps} />

<Checkbox.Group {...inputProps} />

<DatePicker {...inputProps} />

而后你发现在表单渲染前,通过中间件函数你有足够的机会去拓展整个表单的设计,比方:

<code class="typeScript">function middleware(configs: TConfigs) {
  const { itemProps, inputprops }= configs
  
  if(itemProps.name !== 'test'){ return } //筛选咱们须要革新的表单
  
  itemProps.label= 'test2' //咱们更换了label
  
  itemProps.options= [ //咱们更换了选项类组件所须要的options数据
    {label: '浙江', value: 'zj'},
    {label: '福建', value: 'fj'},
  ]
  
  configs.Successor= (props: React.PropsWithChildren<any>) => (
    <div style={{display: 'flex'}}>
      { props.children }
      <Button>同步</Button> 
    </div>
  ) //咱们在表单右侧减少了一个按钮
  
  configs.SuperSuccessor= () => (
    <Form.Item label="newOne" name="newOne">
      <Input />
    </Form.Item>
  ) //咱们甚至用一个全新的表单组件齐全笼罩和抛弃了原有的表单组件
}

Successor 和 SuperSuccessor

对于简单的表单来说,SuccessorSuperSuccessor十分有用,它是开发者利用leggo专一于简单逻辑表单组件的要害。leggo表单设计器中所谓的占位表单组件即是为SuccessorSuperSuccessor的替换操作预留了构造空间。

区别在于,Successor只是对原有的表单组件进行革新(原有的表单组件通过children的形式传给它,itemPropsinputprops仍旧会注入)。而SuperSuccessor则十分激进的笼罩和抛弃了原有的表单组件(itemPropsinputprops也被抛弃)。

<code class="js"><Form.Item {...itemProps}>
  <Successor>
    <Input {...inputprops} />
  </Successor>
</Form.Item> 
<code class="js"><SuperSuccessor />

以上是通过中间件函数一次性的革新schemaModel。而如果你须要随时扭转表单的渲染形式,比方disabled属性,则你能够在任意机会通过调用leggo.updateSchema来实现。每个表单组件是独自重渲染的,所以你也不须要思考性能的问题。如下:

<code class="typeScript">// 能够随时调用
leggo.updateSchema('select', configs => {
  const { inputprops }= configs
  inputprops.disabled= true
})


// 中间件函数实现形式(留神这个函数只会运行一次!):
function middleware(configs: TConfigs) {
  const { itemProps, inputprops }= configs
  if(itemProps.name === 'select'){ 
    inputprops.disabled= true
  }
}

高级利用

好的,让咱们进一步引入更简单的设计场景。假如咱们须要设计一个容许数据联动的表单,日期组件是否必选由“单选”这个组件的值决定。

则咱们只须要通过leggo表单设计器设置数据关联和简略的逻辑运算操作即可。

[{label: '必选日期', value: 1}, {label: '非必选日期', value: 2}]

如果咱们的关联值是在程序运行时能力拿到的,则咱们能够通过在表单理论渲染前传入一个公共状态即可。公共状态既能够是值,也能够是函数,leggo引擎会自动识别。

还有一种常见的场景就是对于SelectRadio等组件须要近程拉取options数据,通过leggo也同样能够很不便实现这样的需要。

带有关联按钮的数据都能够设置关联数据

公共状态引入形式如下:

<code class="typeScript">const publicStates= {
  testvalue: 1084,
  testFunc: () => 'test',
}

function MyForm(){
  const leggo= LeggoForm.useLeggo(schemaModel, middleware, publicStates)
  const [form]= Form.useForm()

  return <LeggoForm leggo={leggo} />
}

leggo表单设计器

演示地址:https://kerrycodes.github.io/

如果你须要在我的项目中间接部署这个表单设计器,则能够间接引入LeggoConfigs组件,onGetSchemaModel属性会在schemaModel生成后主动注入和执行,款式须要手动引入。如下:

<code class="typeScript">import 'leggo/lib/styles/configs.less'

<LeggoConfigs onGetSchemaModel={postSchemaModelData} />

function postSchemaModelData= (schemaModel: TSchemaModel) => {
  console.log('发送schema~~~~~~', schemaModel)
}

重要!

我的项目地址:https://github.com/KerryCodes…

入行快一年了,编乎上没发过答复都攒了20个粉丝了,Github的star仍旧挂0!!!各位大佬能不能动动金手指,让我体验一下有star的快感~


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:手撸一个拖拽式表单生成低代码工具leggo

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址