你有一份章节测试需要完成

你有一份章节测试需要完成

  • 前言
  • 一、将从后台的问题和选项渲染到页面上
  • 二、在data里面的定义好数据
  • 三、将数组进行转换和整理发送给后台,以及后台数据的回显
  • 总结


前言

最近要做的一个网站需要用到章节测试的模块,在参考了慕课的测试模块之后,动手就是一波敲敲敲!!!以下记录一下我的敲敲敲历程。


思路:将题号和答案放进一个数组,通过与渲染的题号进行匹配形成一个新的题号答案数组发送给后台,将返回的结果渲染出来。

一、将从后台的问题和选项渲染到页面上

我这里使用了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里面的定义好数据

 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
                        }

                    })
                }

            },

最后来看一下效果吧!
你有一份章节测试需要完成_第1张图片


总结

经过这么多的弯弯绕绕终于把这个功能给实现了,如果你看了有更好的想法,我们也可以交流一下鸭。

你可能感兴趣的:(html,vue.js,css,javascript,html5)