vue: 动态表单实现(单问题线)
这个是工作中的一个需求,当然需求比较浅,适当的扩展实现了一下,写个博客记录一下当下的逻辑思想
需求如上图,简单来说就是一个select选择不同的答案,后面可以会多出不同的题目。然后就是问题块的概念,一堆问题,这些问题同时间出现且没有先后顺序,则为一个问题块,一个问题块中的一个select的选择,可能触发另一个问题块的出现。
需求需要解决的点:
- 逻辑结构不定,为后端提供
- 层级不定,由逻辑结构决定
- 填到最下面的叶子结点后,获取全部用户所填有效的问题结果
- 有创建和编辑功能,利用答案,反铺该答案所对应的表单
解决思路:
创建3个组件:
- index组件:该表单的入口
- level组件:一个问题块
- end组件:一个表单的最后,也就是提交步骤
铺页面:
在页面中向后端请求获取逻辑结构,将逻辑结构放入index组件,index组件拿到逻辑结构交给level组件,有level组件进行铺第一个根问题块,若问题选择,激活了另一个问题块,则level组件引用本身,循环该问题块,直至遇到‘end’标识符位置,展示提交按钮。
获取答案:
点击end组件的提交按钮,初始化ans的答案空对象,向该组件的父组件进行传值,传值包括ans答案及该组件的逻辑结构,父组件拿到值,将自己的答案添加到ans对象中去,并将自组件传来的逻辑结构放到自己逻辑结构中的child字段中去,再将ans对象和自己更新完的逻辑结构传向自己的父组件,反复操作,直到达到index组件,整理答案,传值页面,有页面展示和向后台传递ans对象。而更新完的逻辑结构也需交给后台保存,以供前台之后修改时恢复表单。
逻辑结构样例:
limitRule: [{
type: 'select',
name: 'wr1,
label: '问题块根-问题1',
ans: null,
child: null,
content: [{
value: 'wr11',
label: ''问题块根-问题1-答案1',
children: [{
type: 'select',
name: 'w11',
label: '问题块1-问题1',
ans: null,
child: null,
content: [{
value: 'w11',
label: '问题块1-问题1-答案1',
children: [{
type: 'end'
}],
}, {
value: 'w11',
label: '问题块1-问题1-答案2',
children: [{
type: 'select',
name: 'wa1',
label: '问题块a-问