阅读 2232

Formily入门实践(formily自定义组件)

前言

Formily 是阿里开源的动态化表单的解决方案,优雅的解决了多种复杂场景的表单的数据、状态管理及夸表单通信问题,同时规避了全量全然的弊端,性能优越。刚好满足我近期工作中的业务需求,啃了将近一周的文档,对 Family 有了初步的了解,后续使用起来再出翻坑指南。

初步了解

Formily基于MVVM的设计原则,常用的基础核心库有@formily/core@formily/react@formily/vue@formily/antd,支持react和vue,同时支持Markup Schema、 JSX以及现在业界最流行的JSON Schema的写法。

Formily 分为了内核层UI 桥接层扩展组件层,和配置应用层,如下图。 内核层是 UI 无关的,它保证了用户管理的逻辑和状态是不耦合任何一个框架。 JSON Schema 独立存在,给 UI 桥接层消费,保证了协议驱动在不同 UI 框架下的绝对一致性,不需要重复实现协议解析逻辑。 扩展组件层,提供一系列表单场景化组件,保证用户开箱即用。无需花大量时间做二次开发。 image.png

核心优势

  • 高性能

  • 开箱即用

  • 联动逻辑实现高效

  • 跨端能力,逻辑可跨框架,跨终端复用

  • 动态渲染能力

核心劣势:学习成本较高,需引多个包,包体积较大。

确实Formily的学习成本还是相对较高的,几大核心库一堆的文档和API会让你眼花缭乱,但是既然要学就要耐下心来,思路理清之后就轻车熟路了。

核心库介绍:

  • @formily/coreViewModel层,负责管理表单的状态,表单校验,联动等等。

  • @formily/react:** Model层**,作为UI 库来接入内核数据,用来实现最终的表单交互效果,对于不同框架的用户,使用有不同的桥接库,这里使用react为例,使用vue安装@formily/vue

  • @formily/antdView层,在Ant Design基础之上封装的开箱即用的组件库。

使用准备

安装依赖,这里以React+Antd 为例

使用yarn


    • yarn add @formily/core


    • yarn add @formily/react


    • yarn add antd moment @formily/antd


or使用npm

  1. npm install --save @formily/core

  2. npm install --save @formily/react

  3. npm install --save antd moment @formily/antd


导入依赖:

import React from 'react' import { createForm } from '@formily/core' import { FormProvider, Field } from '@formily/react' import { FormItem, Input } from '@formily/antd' 复制代码


实例

JSON Schema写法为例:

import React from 'react'; import { createForm } from '@formily/core'; import { createSchemaField, FormConsumer, FormProvider } from '@formily/react'; import { FormItem, Input, Password, Submit, FormLayout, FormButtonGroup } from '@formily/antd'; import * as ICONS from '@ant-design/icons'; //用来创建表单核心领域模型,它是作为MVVM设计模式的标准 ViewModel const form = createForm(); // 创建一个 SchemaField 组件用于解析JSON-Schema动态渲染表单的组件 const SchemaField = createSchemaField({   // 组件列表   components: {     FormLayout,     FormItem,     Input,     Password,   },   // 全局作用域,用于实现协议表达式变量注入   scope: {     icon(name: string) {       return React.createElement(ICONS[name]);     },   }, }); /**初始化一份json schema  * 解析 json-schema 的能力;将 json-schema 转换成 Field Model 的能力;编译 json-schema 表达式的能力  **/ const schema = {   // schema type   type: 'object',   properties: {     layout: {       type: 'void',       'x-component': 'FormLayout',       'x-component-props': {         labelCol: 2,         wrapperCol: 6,         labelAlign: 'right',         // layout: 'vertical',       },       // 属性描述       properties: {         username: {           // schema type           type: 'string',           // 标题           title: '用户名',           // 必填           required: true,           // 字段 UI 包装器组件           'x-decorator': 'FormItem',           // 字段 UI 组件           'x-component': 'Input',           // 字段 UI 组件属性           'x-component-props': {             prefix: "{{icon('UserOutlined')}}",           },         },         password: {           type: 'string',           title: '密码',           required: true,           'x-decorator': 'FormItem',           'x-decorator-props': {             addonAfter: '强度高',           },           'x-component': 'Password',           'x-component-props': {             prefix: "{{icon('LockOutlined')}}",           },         },       },     },   }, }; export default () => {   return (     <FormProvider form={form}>       <FormLayout layout="vertical">         <SchemaField schema={schema} />       </FormLayout>       <FormButtonGroup>         <Submit onSubmit={console.log}>提交</Submit>       </FormButtonGroup>       <FormConsumer>         {() => (           <div             style={{               width: 340,               marginTop: 20,               padding: 5,               border: '1px dashed #666',             }}           >             实时响应-用户名:{form.values.username}           </div>         )}       </FormConsumer>     </FormProvider>   ); }; 复制代码

1638349667(1).png

  • FormProvider组件是作为视图层桥接表单模型的入口,它只有一个参数,就是接收 createForm创建出来的 Form 实例,并将 Form 实例以上下文形式传递到子组件中。

  • FormLayout组件是用来批量控制FormItem样式的组件,这里我们指定布局为水平布局,也就是标签在左,组件在右。

  • FormConsumer组件是作为响应式模型的响应器而存在,它核心是一个render props模式,在作为 children 的回调函数中,会自动收集所有依赖,如果依赖发生变化,则会重新渲染,借助 FormConsumer 我们可以很方便的实现各种计算汇总的需求。

  • FormButtonGroup组件作为表单按钮组容器而存在,主要负责按钮的布局。

  • Submit组件作为表单提交的动作触发器而存在,其实我们也可以直接使用 form.submit 方法进行提交,但是使用 Submit 的好处是不需要每次都在 Button 组件上写 onClick 事件处理器,同时它还处理了 Form loading 状态,如果 onSubmit 方法返回一个 Promise,且 Promise 正在 pending 状态,那么按钮会自动进入 loading 状态。

注意:使用前还需要了解,Formily已经完全放弃对IE的兼容,如需兼容IE,慎用!!!


作者:梦鹿
链接:https://juejin.cn/post/7036661455520792583


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐