带你实现一个表单系统(1)

不知道小伙伴们有没有体验过雪梨表单,可以点过去体验一下。

配置完成后就生成一个分享链接,分享出去收集信息。

刚好本人近期有类似的需求需要实现,因此写文章记录一下实现的思路以及过程中遇到的一些问题。本篇只分析核心需求和大致的实现思路。

首先分析一下核心的功能点

  1. 拖拽,表单组件可以从左边拖拽到中间区域。到中间区域后,也可以上下拖拽实现表单项之间的排序。
  2. 配置,配置表单项是否必填、配置默认提示语、选择类型的配置选项、数值类型的配置单位等。
  3. 逻辑,给表单项某些选项配置逻辑。

实现思路的分析

虽然我没法拿到雪梨表单的源代码过来进行分析,但是能拿到雪梨表单在调用保存接口时保存的数据。其中的一个字段questions如下,是整个表单系统生成核心数据,整个表单系统就是围绕这个数组进行增删改查。

json 复制代码
"questions": [
            {
                "id": "65a350e3e12f0008",
                "title": "数字",
                "description": null,
                "type": "question/number",
                "valueType": 1,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": false,
                "content": "{\"placeholder\":\"请输入数字\",\"min\":\"-5\",\"max\":\"-1\"}"
            },
            {
                "id": "65085015e16e00a4",
                "title": "下拉选择",
                "description": null,
                "type": "question/select",
                "valueType": 3,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": true,
                "content": "{\"placeholder\":\"请选择\",\"choiceSeed\":3,\"maxChoice\":1,\"minChoice\":0}",
                "options": [
                    {
                        "id": 1,
                        "url": null,
                        "sort": 0,
                        "text": "选项一"
                    },
                    {
                        "id": 2,
                        "url": null,
                        "sort": 1,
                        "text": "选项二"
                    },
                    {
                        "id": 3,
                        "url": null,
                        "sort": 2,
                        "text": "选项三"
                    }
                ]
            },
            {
                "id": "65685116baf20035",
                "title": "多选",
                "description": null,
                "type": "question/multi-choice",
                "valueType": 3,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": true,
                "content": "{\"otherText\":\"其他\",\"showOther\":false,\"layoutType\":\"vertical\",\"minChoice\":0,\"choiceSeed\":3}",
                "options": [
                    {
                        "id": 1,
                        "url": null,
                        "sort": 0,
                        "text": "选项一"
                    },
                    {
                        "id": 2,
                        "url": null,
                        "sort": 1,
                        "text": "选项二"
                    },
                    {
                        "id": 3,
                        "url": null,
                        "sort": 2,
                        "text": "选项三"
                    }
                ]
            },
            {
                "id": "65aa5199baf200fc",
                "title": "文本",
                "description": null,
                "type": "question/text",
                "valueType": 1,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": false,
                "content": "{\"placeholder\":\"请输入内容\"}"
            },
            {
                "id": "65c25156baf200e2",
                "title": "多行文本",
                "description": null,
                "type": "question/textarea",
                "valueType": 1,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": false,
                "content": "{\"placeholder\":\"请输入内容\"}"
            },
            {
                "id": "654b5100baf20024",
                "title": "数字",
                "description": null,
                "type": "question/number",
                "valueType": 1,
                "isRequired": true,
                "isSortable": false,
                "isMultiple": false,
                "content": "{\"placeholder\":\"请输入数字\"}"
            }
        ]

从左边拖拽或者点击一项生成到中间渲染的区域,其实就是往这个questions中新增一项。然后对新增这一项进行配置,就是把questions中新增的这一项数据放到右边配置区域进行配置,比如其中的isRequired就是配置该项是否必填的字段。最后都是得到questions这么一个对象数组,并且把它保存到数据库。大体上就是这么个实现思路。

相关推荐
我只会写Bug啊3 小时前
Vue文件预览终极方案:PNG/EXCEL/PDF/DOCX/OFD等10+格式一键渲染,开源即用!
前端·vue.js·pdf·excel·预览
扯蛋4384 小时前
LangChain的学习之路( 一 )
前端·langchain·mcp
Mr.Jessy4 小时前
Web APIs学习第一天:获取 DOM 对象
开发语言·前端·javascript·学习·html
ConardLi5 小时前
Easy Dataset 已经突破 11.5K Star,这次又带来多项功能更新!
前端·javascript·后端
冴羽5 小时前
10 个被严重低估的 JS 特性,直接少写 500 行代码
前端·javascript·性能优化
rising start5 小时前
四、CSS选择器(续)和三大特性
前端·css
一 乐6 小时前
高校后勤报修系统|物业管理|基于SprinBoot+vue的高校后勤报修系统(源码+数据库+文档)
java·前端·javascript·数据库·vue.js·毕设
爱喝水的小周6 小时前
《UniApp 页面配置文件pages.json》
前端·uni-app·json
mapbar_front6 小时前
React中useContext的基本使用和原理解析
前端·react.js
贪婪的君子6 小时前
【每日一面】实现一个深拷贝函数
前端·js