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>

最後:最終這種的解決方案並不滿意,若有其他思路或改進方法,請指教,謝謝

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