vue: 動態表單實現(多問題線)
之前寫了一篇單問題線,這次寫的是多問題線的邏輯思想。
如圖,所謂的多問題線就是若問題塊1的select1選了A,select2選了A,則會出現問題塊3和問題塊5,此時問題塊3和問題塊5是同級的,且不在一個問題線上,所以該次答題,至少有兩條線上的答案需要獲取。
這種情況下,上次的邏輯思想就無法解決該情況,就有了一個新的解決思路來解決,並且能解決多問題線的思路必能解決單問題線的問題。
需求需要解決的點:
- 邏輯結構不定,爲後端提供
- 層級不定,由邏輯結構決定
- 填到最下面的葉子結點後,獲取全部用戶所填有效的問題結果
- 有創建和編輯功能,利用答案,反鋪該答案所對應的表單
解決思路:
創建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>
最後:最終這種的解決方案並不滿意,若有其他思路或改進方法,請指教,謝謝