preface

I first met Formily a few years ago and wrote an article about it: Notes on the Use of UForm. Unfortunately, it hasn’t been used in real business.

By February of last year, by coincidence, v1.x was being used in business projects. It seems that the formily authors were pushing for a v2.x beta at the time, but when they realized that it was basically a cliff upgrade, they gave up. After all, they had developed a lot of code with 1.x at that time, so they really didn’t want to move. Of course, you could have used the beta version of Formily2.x with a micro front end, but there was no need for a micro front end.

Unfortunately, the project team I was working in was disbanded in September last year for some reasons, and then I joined a new team, so I had the chance to try Formily again, so I decided to use the beta version, which experienced some instability during this period. Fortunately, the V2 version was officially upgraded later, which was much better.

New period

At the beginning, I looked up various documents and asked colleagues who had used Formily to write it. Gradually, I understand that there are only two ways to write:

  • json schema
  • Pure JSX

In fact, there is a third way to write markup schema in the document, but I think it is quite weak. For example, if you want to write a div structure in the middle, it will insert the div at the end (obviously not satisfying your own needs).

Our business scenario is logistics Sass, with N form items on the details page. Since I personally prefer to write ABOUT JSX, I wrote about JSX at the beginning. But after writing, I found that I was very tired, and some of the code was similar, so I decided to encapsulate another layer. It was JSON, but the type was like this:

export interface ISchema {
  component: 'Row'; componentProps? : RowProps; areaList: {key: string; colSpan? :string; componentProps? :any; // Can be props for col or props for divuseGrid? :boolean; formItemProps? : IFormItemProps; gridProps? : { minWidth? :number | number[]; maxWidth? :number | number[]; minColumns? :number | number[]; maxColumns? :number | number[]; breakpoints? :number[]; columnGap? :number; rowGap? :number; colWrap? :boolean; }; children: { name? :string; title? :string;
      key: string;
      type: 'basic' | 'custom';
      component: string; dataSource? : {label: string;
        value: any; } []; rules? : Rule[]; componentProps? : { [key:string] :any; }; fieldProps? : { [key:string] :any; }; formItemProps? : IFormItemProps; gridColumnProps? : { gridSpan? :number; }; } []; } []; }Copy the code

Just a quick explanation of why it was designed that way. Because our detail page layout can be broken up into one or more blocks, each block contains the Grid layout.

Then I did some experiments with it, and it worked really well.

Growth period

The json schema provided by Formily does not match the json schema provided by formily.

Until the leader asked me to consider using low code to configure the JSON. There are mainly several considerations:

  • Permissions (buttons/form items)
  • Check rules (try to use the same set of front and back ends)
  • internationalization

Seriously, I’m starting to scratch my head. After carefully reading the JSON Schema protocol provided by Formily, I found that it is well designed and has a ready-made Designer.

In the process of changing back to JSON Schema, I re-examine the design of former ISchema scheme, and find that the user-defined component I write does not consider type: void at all, so that basePath will be reset in some places, which is actually anti-pattern.

The rock design

Rock is a code name for this low code. Let me share it briefly.

Prepend content

The result of this low-code platform is JSON Schema.

In business engineering, get all the JSON list under the current page based on the page (a page is fragmented in some places, so it will be broken into multiple JSON, including the form that may exist in the popover).

The corresponding block simply renders the JSON schema matching the name.

Page section

The new pop-up window

It is important to explain why there are buttons. After the save button of the business project is clicked, the corresponding button should be found according to the request URL. There will be two things in the button:

  • Permission (i.e. does the user have permission to click save)
  • Find all of its corresponding JSON lists (to get all of the form itemsrule list)

There will also be a special add, delete, change and search button. One of the points to consider is permissions, such as permissions between code components, for example:

{{a}} && {{b} || {{c}
Copy the code

A /b/c is the permission code, why use interpolation here? Because when you get to the front end, you need replace to be true or false

The rock list

Simple function description:

  • Edit: what’s inside the popover
  • JSON edit: Formily desiger
  • delete
  • Copy: This is mainly generated by copying the JSON editorjson schema

Designer Details

More in depth

permissions

There are two places for permissions:

  • button
  • The form item

Button, as we’ve already seen, is just giving it a permission expression. Front-end processing can be done.

The form processing is slightly more subtle, we can extend an X-permission. And then when you parse the schema, you can process it.

Schema.registerPatches(schema= > {
  // sole.log(schema['x-permission']);
  const permission = schema['x-permission'];
  if (permission) { // Do some processing here
    schema['x-display'] = 'none';
  }
  return schema;
});
Copy the code

Validation rules

 <Button
    onClick={async() = > {const json = transformToSchema(designer.getCurrentTree());
      await saveDetail({
        json: json.schema,
        processJson: filterVoidSchema(json.schema as ISchema),
        relaId: id,
        name,
      });
      message.success('Saved successfully');
    }}
 >
    <TextWidget>Save</TextWidget>
</Button>
Copy the code

Look at the code above, when saving, in fact, is the back end of the two JSON, one is the front-end need JSON, one is the back-end need JSON.

The function name is fiterVoidSchema. Filter out the void schema, because the front end layout creates a lot of redundant JSON items. It is ok to let the back end do recursion, but the front end is more convenient.

The backend can quickly get the X-rules field, so as to achieve the parity of the front and back ends

Handling of internationalization

I don’t know if you’ve ever used Kiwi. We adapted it a little bit because it had Google Translate built in, and then we changed it to Baidu Translate and added some extensions of our own.

Then again, this is a better solution, but not an optimal one. Because of the increase in copywriting, international documents will continue to grow, such as the following two paragraphs of copywriting:

Are you sure you deleted it? Are you sure you want to delete it?Copy the code

It actually means the same thing. The internationalization plan of our platform is as follows:

  1. The internationalization of label is processed by the back end of my uploadjson schema
  2. Prompt class, write a unified method, incoming or Chinese, outgoing value depends on the current locale. Of course the page will load a file (json for key and value).
  3. Page inside its Own Chinese (this part of the temporary no idea, maybe or will be usedkiwi)

Things to do in the future

There are still a lot of things to do, such as referencing the rock props.

To be honest, scratching my head… Worry my hair is quick to drop light, have similar needs, ideas of friends, can communicate together.

Write in the last

As for how to use Formily, I haven’t mentioned it much in this article, so you can refer to the documentation. Let’s face it, there are costs, but if you learn it once, you’ll benefit for life (it’s impossible, but you’ll get a bonus).

Formily Designer is a bit more scalable than the visualization engine tools (in this case, we’re adding a component that needs to work in many places), but each has its own advantages.