vue: 动态表单实现(多问题线)

vue: 动态表单实现(多问题线)

之前写了一篇单问题线,这次写的是多问题线的逻辑思想。

在这里插入图片描述
如图,所谓的多问题线就是若问题块1的select1选了A,select2选了A,则会出现问题块3和问题块5,此时问题块3和问题块5是同级的,且不在一个问题线上,所以该次答题,至少有两条线上的答案需要获取。

这种情况下,上次的逻辑思想就无法解决该情况,就有了一个新的解决思路来解决,并且能解决多问题线的思路必能解决单问题线的问题。

需求需要解决的点:

  1. 逻辑结构不定,为后端提供
  2. 层级不定,由逻辑结构决定
  3. 填到最下面的叶子结点后,获取全部用户所填有效的问题结果
  4. 有创建和编辑功能,利用答案,反铺该答案所对应的表单

解决思路:
创建3个组件:

  • index组件:整个表单

主要逻辑:
标示自己的父问题状态

铺页面:
循环逻辑结构数组,若fa为null或rule[fa].ans的答案等于faV时展示

提交答案:
循环逻辑结构数组,若fa为null或rule[fa].ans的答案等于faV时,获取答案

逻辑结构样例:

           rule:[{
                type: 'select',
                name: 'w1',
                label: '问题1',
                ans: null,
                fa: null,
                content: [{
                    value: 'w11',
                    label: '问题1-答案1',
                }, {
                    value: 'w12',
                    label: '问题1-答案2',
                }]
            }, {
                type: 'select',
                name: 'w2',
                label: '问题2',
                ans: null,
                fa: 0,
                faV: 0,
                content: [{
                    value: 'w21',
                    label: '问题2-答案1',
                }, {
                    value: 'w22',
                    label: '问题2-答案2',
                }]
            }]
对象属性 描述
type 问题类型
name ans对象中该答案所对应的键
ans ans对象中该答案所对应的值
label 页面展示文字
fa 该问题的先置问题的index值,若没有则为null
faV 该问题的先置问题所对应的答案,若没有则为null
content 问题为select的时候,下拉框内容

缺点:
逻辑结构的数组可读性差,规范要求严格(努力完善中)

局部代码:

<template>
    <el-form :label-width="'150px'" label-position="right" >
        <template v-for="(item, index) in rule">
            <el-form-item
            :key="index"
            :label="item.label ? item.label: ''"
            style="width: 100%"
            v-if="item.type == 'select' && ((!item.fa && item.fa != 0) || rule[item.fa].ans == item.faV)"
            >
                <el-select v-model="item.ans" placeholder="请选择">
                    <el-option v-for="(option, option_index) in item.content" :key="option.label" :label="option.label" :value="option_index"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item
            :key="index"
            :label="item.label ? item.label: ''"
            style="width: 100%"
            v-if="item.type == 'textarea' && ((!item.fa && item.fa != 0) || rule[item.fa].ans == item.faV)"
            >
                <el-input type="textarea" v-model="item.ans"></el-input>
            </el-form-item>
        </template>
        <el-form-item>
            <div style="text-align:center; width: 500px;">
                <el-button size="small" type="primary" style="margin-right: 50px;" @click="submitAns">确定</el-button>
                <el-button size="small">取消</el-button>
            </div>
        </el-form-item>
    </el-form>
</template>
<script>
import limitLevel from './LimitLevel';
import {
    deepClone
} from '../../utils/utils'

let self = null;

export default {
    components: {},
    data() {
        return {}
    },
    created() {
        self = this;
    },
    props: ['rule'],
    methods: {
        submitAns() {
            let ans = {};
            for(let i = 0; i < this.rule.length; i++) {
                let item = this.rule[i];
                if((!item.fa && item.fa != 0) || this.rule[item.fa].ans == item.faV) {
                    if (!item.ans && item.ans != 0) {
                        this.$message({
                            type: "warning",
                            message: "请检查您的" + item.label + "是否填写"
                        });
                        return false;
                    }
                    ans[item.name] = item.ans;
                }
            }
            console.log(ans);
        }
    }
}
</script>

最后:最终这种的解决方案并不满意,若有其他思路或改进方法,请指教,谢谢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章