最近要做的一个网站需要用到章节测试的模块,在参考了慕课的测试模块之后,动手就是一波敲敲敲!!!以下记录一下我的敲敲敲历程。
思路:将题号和答案放进一个数组,通过与渲染的题号进行匹配形成一个新的题号答案数组发送给后台,将返回的结果渲染出来。
我这里使用了iview UI组件的单选框组,这个单选框组绑定的是label的值。做的是单选题与判断题混合显示的,通过v-if来判断题型控制题型的显示与隐藏。
<div>
<div class="titleLine">
<h1 style="padding-left: 1vw;color: #1F6BCB;">章节测验<span style="float: right;color: #FF3F00;margin-right: 1%;" v-if="show1">你的得分为:{{sum1}}.00</span>//我的在这里用v-if来控制显示总的得分
</h1>
</div>
<div class="con" v-for="(item,i,index) in tem1">//将获取的题目进行遍历渲染显示
<!-- 单选题 -->
<div v-if="item.type===1">//判断是否是类型1的单选题,如果是就显示单选题
<h2><span style="font-size: 1.2rem;">{{i+1}}</span> <span
style="background-color: #E3F8FF;border: 1px solid #BFDFFF;padding: 2px;">单选</span>
{{item.question}}( )</h2>
<RadioGroup v-model="answerInfo1[item.tesId]" vertical style="padding-left: 0.5vw;"
false-value="#">//这里的item.tesId很重要,是通过题号进行标识,并且以{题号:答案}的键值对的形式存到数组里面去
//因为获取的数据没有ABCD,我只能自己写ABCD选项,然后把四个选项的内容一个个地获取出来显示
<Radio label="A" :checked.native="item.checked">
<span>A. {{item.options[0]}}</span>
</Radio>
<Radio label="B">
<span>B. {{item.options[1]}}</span>
</Radio>
<Radio label="C">
<span>C. {{item.options[2]}}</span>
</Radio>
<Radio label="D">
<span>D. {{item.options[3]}}</span>
</Radio>
</RadioGroup>
</div>
<!-- 判断题 -->
<div v-if="item.type===2">//判断是否是类型2的判断题,如果是就显示判断题
<h2><span style="font-size: 1.2rem;">{{i+1}}</span> <span
style="background-color: #EEEEEE;border: 1px solid #DDDDDD;padding: 2px;">判断</span>
{{item.question}}( )</h2>
<RadioGroup v-model="answerInfo1[item.tesId]" vertical style="padding-left: 0.5vw;"
false-value="#">
//从后台获取的数据是对就是true、错就是false,所以我这里做了一下转换,换成“√”与“×”显示
<Radio label="true" :checked.native="item.checked">
<span>A. √</span>
</Radio>
<Radio label="false">
<span>B. ×</span>
</Radio>
</RadioGroup>
</div>
//如果后台的数据有图片就显示图片,没有就不显示
<div v-if="item.img_urls" style="width: 40%;">
<img style="width: 100%;" :src="baseURL+item.img_urls" />
</div>
//我这里一道题是10分的,如果这道题是对的就有10分。通过分数来控制结果对错的显示模块。
//这里是答案选对的时候显示的内容
<div id="i" style="background-color: #F8F8F8;" v-if="mark1[i]===10">
<span style="color: #79A900;">正确答案:</span>
<span style="color: #79A900;font-size: 1.5rem;">{{trueAnswer1[i]}}</span>
<span style="color: #79A900 ;"> 你选对了</span>
<span
style="color: #79A900 ;float: right;margin-top:2%;margin-right: 1%;">{{mark1[i]}}.00/10.00</span>
<Icon style="color: #79A900 ;font-size: 1.2rem;font-weight:bolder;float: right;margin-top:2%;"
type="md-checkmark" />
</div>
//这是答案选错的时候显示的内容
<div style="background-color: #FFF3F3;" v-if="mark1[i]===0">
<span style="color: #FF3F00;">正确答案:</span>
<span style="color: #FF3F00;font-size: 1.5rem;">{{trueAnswer1[i]}}</span>
<span style="color: #FF3F00 ;"> 你错选为{{myAnswer1[i]}}</span>
<span style="color: #FF3F00 ;float: right;margin-top: 2%;margin-right: 1%;">
{{mark1[i]}}.00/10.00</span>
<Icon style="color: #FF3F00 ;font-size: 1.2rem;font-weight:bolder;float: right;margin-top: 2%;"
type="md-close" />
</div>
</div>
<button @click="handler1()">提交</button>
<button @click=cencel1()>重填</button>
</div>
data() {
return {
tem1: [],
answerInfo1: [],
trueAnswer1: [],
myAnswer1: [],
mark1: [],
sum1: '',
show1: false,
baseURL: '',//这个是我在页面一开始加载的时候就获取的全局域名,主要用来图片的显示
}
},
handler1() {
let value = this.answerInfo1//v-model绑定的答案数组
const tem1 = this.tem1 //从后台获取的问题和选项的数据数组
//使用Object.keys() 获取答案数组的length,检查题目是否完成了,我这里只显示10道题。
if (Object.keys(value).length < 10) {
this.$Message.warning('你还有题目没做完!请先完成再提交')
} else {
let answer1 = []
let tem = []
for (var i in tem1) {//遍历从后台获取的数据数组
var key = tem1[i].tesId //获取题号
tem['x' + key] = tem1[i].answer[0]
//将题号和答案加进新的数组,这里的'x'是随便定义的,但是也很重要,因为没有加这个的话,数组是按从小到大排列的,但是我从后台获取的题目是随机的,渲染的时候不是题号从小到大排列的。
}
for (var j in tem) {//对新的数组的键值进行遍历
for (var k in value) {//对v-model绑定数组的键值进行遍历
if (k === j.slice(1)) {//这里的slice(1)是获取键值'x'后面的题号
//如果绑定的数组的键值与新的数组的键值相等就以'题号#答案'的形式添加到新的数组里面
answer1.push(k + '#' + value[k])
}
}
}
//通过qs的{ arrayFormat: 'repeat' },可以将一个数组发送给后台
this.$axios.post(`/admin/testSet/commitTest`, qs.stringify({ answer: answer1 }, { arrayFormat: 'repeat' }), {
headers: {
'token': localStorage.getItem('token')
},
}).then(res => {
//将后台返回的答案进行处理,因为判断对错的后台返回的是true和false,我这里处理一下变成“√”和“×”渲染到页面上显示
const trueAnswer1 = res.data.extended.testSet.answer
let TA = []
for (var i in trueAnswer1) {
if (trueAnswer1[i] === 'true') {
TA.push('√')
} else if (trueAnswer1[i] === 'false') {
TA.push('×')
} else {
TA.push(trueAnswer1[i])
}
}
this.trueAnswer1 = TA
//将后台返回的我提交的答案进行处理
const myAnswer = res.data.extended.testSet.myAnswer
let MA = []
for (var i in myAnswer) {
if (myAnswer[i] === 'true') {
MA.push('√')
} else if (myAnswer[i] === 'false') {
MA.push('×')
} else {
MA.push(myAnswer[i])
}
}
this.myAnswer1 = MA
this.mark1 = res.data.extended.testSet.mark
this.sum1 = res.data.extended.testSet.sum
//如果有总分的话,v-if控制的总分显示就会显示总分
if (this.sum1 !== '') {
this.show1 = true
}
})
}
},
经过这么多的弯弯绕绕终于把这个功能给实现了,如果你看了有更好的想法,我们也可以交流一下鸭。