需求来了,有的时候想要创建一个表单,这个表单是可以动态配置的,比如试卷啊,调查问卷之类的,表单的数据是调用接口获得的,这该如何实现呢? 我看很多代码都是使用vue2 option API写的,我当时做这个需求的时候也是这样写的,虽然知道setup的写法,但是平时用的还是比较少,但是现在vue3都出来那么久了,就用Composition Api再写一遍吧,顺便多练习一下组合式api。
一、数据结构样式
像这样可以动态配置的表单,题目包括选项一般都是有id的。当然具体的数据结构和公司有关。
服务器给的表单列表数据结构如下:
| 字段名 | 意义 |
|---|---|
| id | string 题目的id |
| type | string 题目的类型,目前我这里有radio、checkbox、input、textarea,分别表示单选、多选、输入、多行文本输入,可以根据自己的需求添加别的类型 |
| label | string 题目的文字描述 |
| options | array 单选或多选题的选项,数组结构类似于[{label:labelValue,id:id}] |
| rules | 表单校验规则 |
二、开始绘制表单
首先创建一个.vue文件。
这里我使用了arco-design组件库的组件绘制表单,组件库一般来说大同小异,使用element或者ant-design其实也是差不多的。
目前要渲染一个这样的数组,具体代码到最后再放出。
<a-form ref="formRef" :model="form" @submit="handleSubmit">
<a-form-item v-for="(item) in formList" :field="item.id" :key="item.id" :label="item.label" :rules="item.rules">
{{ item }}
</a-form-item>
<a-form-item>
<a-button html-type="submit">提交</a-button>
</a-form-item>
</a-form>
这样就可以把表单展示出来了,handleSubmit事件如果不想放在a-form标签上,想放到按钮上,其实也是无所谓的,每个组件库的写法会有一些不一样,都是可以实现的,使用v-for循环数组,这里的field是用来校验的
现在只是在中间简单地放了item上去,接下去就是根据每道题目对应的type,在填入对应的组件了,我是直接使用if else,根据type简单粗暴地判断类型了,但是感觉有许多重复的代码,如果有更好的方法欢迎在评论区讨论。
像radio-group或者checkbox-group,都有options作为选项,一般来说组件库options的数据结构是这样的,如下图:
但是我们之前的格式是id和label,可以写个for循环自己遍历一下,加一个value就可以了,如果是select选择框的话可以用field-names,那就不用写循环了
动态表单的完整代码如下。点script可以看到代码,因为我这里用了组件库的组件,也没引入包什么的,所以运行的时候看不到什么效果。
最后来实验一下,必填项没有填会报错
正确输入表单内容,可以展示form,如果是选择题,id对应的是答案的id,如果是填空题,那就是填入的内容