Skip to content

Form configuration generation plan

About 641 wordsAbout 2 min

development

2022-03-17

A simple form configuration generation solution based on vue3 can be used as a reference for ideas.

Preface

This plan is a plan that an individual needs to implement a simple form configuration generation when doing a certain project. The end result is to be rendered into a form through a form configuration, and supports:

  • Supports multiple form field types (single-line text/multi-line text/number/drop-down/multi-select/single-select, etc.), and supports nested fields (object/array)
  • Support field verification
  • Support conditional judgment to show/hide form fields
  • Support field grouping display

Tips

Complete code repository address: formative

Effect display

**Generate form by configuration: ** demo 1

**When the fields configured are objects or arrays: ** demo 2

**Group display of configured fields: ** demo 3

Solution Description

By configuring the form, it is necessary to clarify how to implement the form field to associate it with the corresponding form component and implement the data binding.

Protocol Configuration

A protocol is agreed to represent a certain field in the form through an object:

FieldSchema:

{
  "type": "Denotes the type of field, such as single-choice, multiple-choice, single-line text, multi-line text, etc.",
  "field": "represents the name of the field",
  "label": "Denotes the label displayed in the field",
  "default": "field default value",
  "description": "Field description information, used as prompt information"
}

For full forms, configure them using the array form of FieldSchema[].

Form fields are associated with components

In vue, components can be rendered through the h(component, attrs[, children]) rendering function, Through the h() function, different components can be rendered dynamically.

We can use this feature to map the field type to the corresponding component, and use the field type to obtain the corresponding component through the mapping relationship. Then call h() for rendering.

// Field type and component map
const componentMap = {
  radio: RadioField,
  checkbox: CheckboxField,
  text: TextField,
  select: SelectField,
}
{
 name: 'Field',
 props: ['fieldType'],
 setup(props) {
 return () => h(componentMap[props.fieldType])
 }
}

Form Data Binding

For form data, data initialization is required, and the corresponding Field component can read and write the data.

In vue, we can use the provide/inject API to inject the root component of the form component through provide(), internally In FieldComponent, the corresponding data is obtained through inject() and read and write.

/**
 * Enter data through provide
 */
const useFormDataProvide = (formData: FormData): FormInjectKey => {
  const key: FormInjectKey = Symbol('formData')
  provide(key, formData)

  return key
}

/**
 * Get data through inject
 */
const useFormData = (key: FormInjectKey): FormData => inject<FormData>(key)!

Since it is necessary to support multi-level data structures generated when fields are objects/arrays, it is also necessary to consider the FieldComponent for FormData.a.b Read and write deep data.

FormData.a.b can be read and written by implementing dotPath, in the form of FormData['a.b'], so FieldComponent You only need to know the dotPath field path of a.b to read and write the form data obtained by inject().

const useDotPath = <T = any>(model: FormData, dotKey: ComputedRef<string>) => {
 const binding = computed<T>({
 set(data) {
 setDotPath(model.value, dotKey.value, data)
 },
 get() {
 return getDotPath(model.value, dotKey.value)
 },
 })

 Return binding
}

Technology implementation

In the formative repository, a library for configurable forms is implemented through this solution.

  • src/components/Formative.tsx file as form root component.
  • src/components/Field.tsx file is used to render the form field as a dynamic selection of corresponding components based on the form field.
  • The src/components/Group.tsx file implements grouping form fields.
  • src/components/[other].tsx Other files implement various form field components.

If you are interested in learning the details, you can read formative source code. I made relevant code comment instructions at key locations.

At the same time, you can directly pull the source code and run it locally. And authorize the code to use.