动态表单设计

前言

这一章节主要讲解动态表单是如何设计以及具体的数据流转和实现流程该文章不会涉及到代码细节,更多的是学习整个设计器的实现思路。例如schema数据是如何闭环如何流转如何设计

动态表单设计

接下来看一下动态表单是如何设计、渲染以及运行的,其经过如下步骤:
schema json数据的定义 -> 模版区域渲染 -> 编辑区域渲染 -> 组件配置区域-> 推送后端 -> 拉取在对应页面渲染

1. 表单设计器的整体流程图

经过上面的整体图片对动态表单设计有了大概得认知,接下来拆分每一个模块的具体实现

2. schema json数据的定义 (模版数据定义)

动态表单最重要的就是 schema json的定义,这里推荐参考formilyjs设计器的schema定义。

  • key:表示对应那个物料组件名称。
  • data:表示该组件可动态配置的属性 (每个组件都有差异性)


key值物料组件库(编辑器)的组件映射关系定义。

这样子就可以通过key找到对应的编辑区组件配置区组件

3. 模版区域渲染(编辑器)

遍历schemaJson数据渲染到对应的模版列表

4. 编辑区域渲染(编辑器)

将模版列表的元素拖动到编辑区域时, 会将该组件的schema数据添加到store的list里,然后在编辑区域遍历该list数据通过key从module数据里查找到对应的编辑FormInput配置组件FormInputConfig

5. 配置区域渲染(编辑器)

配置区渲染的组件是根据 点击那个编辑区域的组件来决定的,例如点击了FormInput组件那么将渲染FormInputConfig组件,FormInputConfig组件内部每一项的值是通过读取store里的item进行赋值的。修改某一项的也将同步到

经过上面的步骤,我们就完成了整个表单设计器的流程,store里存储的list数据也就是我们通过配置生成的shemaJson数据然后推送给后端保存。

那么接下来我们就来实现如何在页面中使用配置好的schemaJson来生成面向用户的表单页面

6. 页面表单渲染实现

经过上面的步骤我们就自定义好了动态表单的数据,如下图schema json数据

  • input输入框、必填、标题为"客户姓名"、提交给后端字段为"customer"、最大长度为10、提示语为"请输入客户姓名"
  • radio单选框、非必填、标题为"客户性别"、提交给后端字段为"gender"、选项为"男"|"女"
ts 复制代码
// 1. 页面A
const schemaJson = [
    {
        lable: '单行文本',
        key: 'FormInput',
        icon: 'icon-danhangwenben',
        id: generateRandomID(),
        data: {
          filed: 'customer'
          title: '客户姓名',
          required: 1,
          maxlength: 10,
          value: undefined,
          placeholder: '请输入客户姓名',
        },
    },
]

const state= reactive({
  formState:{}
})
  
<a-form  ref="formRef" :model="state.formState">
  <DynamicForm
      v-for="item in schemaJson"
      :config="item"
      :name="i.data.field"
      // :name="['contactInformation', index, i.data.field]"
      :key="i.data.field"
      v-model="state.formState[i.data.field]"
  ></DynamicForm>
</a-form>

const confirm = () =>{
  // 使用form自带的校验方式,进行必填、属性值的校验
  formRef.value.validate()
}


// 2. DynamicForm/index.vue

<component :is="formItem" :data="config.data" :name="name" @update="updateValue"></component>

const emit = defineEmits(['update:modelValue', 'update'])
const props = defineProps({
    config: {
        type: Object,
        default: {},
    },
    name: {
        type: [String, Array],
    },
})

const module ={
  FormInput: {
    value: DynamicInput,
  },
}

// 通过config渲染对应的组件
const formItem = computed(() => {
    return module[props.config.key].value
})

// 3. DynamicInput.vue组件
<a-form-item
        :label="data.title"
        :name="name || data.field"
        :rules="[{ required: data.required, min: data.minlength, message: data.placeholder,  }]"
    >
       <a-input
            :disabled="data.disabled"
            :title="data.value"
            :placeholder="data.placeholder"
            v-model:value="data.value"
            :maxlength="data.maxlength"
            :showCount="isSHowCount"
            @change="updateValue"
       />
</a-form-item>

经过上述代码,我们就实现了将schemaJson数据渲染成input输入框。 对于属性值的校验通过from表单自带的校验方式即可。

Tips: 表单的name可以是数组即可以校验数组里的某个元素。

7. 总结

经过上面六个步骤我们完成了表单设计器的实现以及动态表单页面的渲染。 当然其还有不足的地方,例如:

  • 没有版本的概念,导致后续修改某个元素属性必须要兼容之前的版本否则报错
  • shcemaJson协议数据设计的不够通用,暂未考虑无缝接入市面主流的UI库
  • 整体项目不具备工程化以及不具备出码能力,没办法直接通过schema生成一个完成的项目

对于上述问题,需要等我研究[阿里低代码引擎](https://lowcode-engine.cn/site/docs/guide/quickStart/intro)之后才能给出具体的方案

相关推荐
蟾宫曲3 小时前
在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
前端·npm·vue3·vite·element-plus·计时器
秋雨凉人心3 小时前
简单发布一个npm包
前端·javascript·webpack·npm·node.js
liuxin334455663 小时前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
qq13267029403 小时前
运行Zr.Admin项目(前端)
前端·vue2·zradmin前端·zradmin vue·运行zradmin·vue2版本zradmin
魏时烟5 小时前
css文字折行以及双端对齐实现方式
前端·css
2401_882726485 小时前
低代码配置式组态软件-BY组态
前端·物联网·低代码·前端框架·编辑器·web
web130933203986 小时前
ctfshow-web入门-文件包含(web82-web86)条件竞争实现session会话文件包含
前端·github
胡西风_foxww6 小时前
【ES6复习笔记】迭代器(10)
前端·笔记·迭代器·es6·iterator
前端没钱6 小时前
探索 ES6 基础:开启 JavaScript 新篇章
前端·javascript·es6
m0_748255266 小时前
vue3导入excel并解析excel数据渲染到表格中,纯前端实现。
前端·excel