Vue实现一个简单的答题案例(单选/多选)

1、html

<template>
  <div class="root-div">
    <div v-for="(item,index) in question" :key="index" v-show="index==idx" class="question">
      <div class="title">
        <span class="select" v-if="item.ismultiple">多选</span>
        <span class="select" v-else>单选</span>
        题目:{{item.name}}
        <span class="answer" v-show="answerShow">答案:{{item.answer}}</span>
        <span style="float: right;">{{idx+1}}/{{question.length}}</span>
      </div>
      <div>
        <div :class="val.checked ? 'bgc' : ''" v-for="val in item.option" :key="val.id" class="list" @click="handleCilck(val)">
          {{val.letter}}.{{val.name}}</div>
      </div>
    </div>
    <div class="btn-box">
      <button @click="back()" :style="idx == 0 ? 'background-color:#ccc;':''"
        :disabled="idx == 0 ? true : false">上一题</button>
      <button @click="next()" :style="idx == question.length - 1 ? 'background-color:#ccc;':''"
        :disabled="idx == question.length - 1 ? true : false">下一题</button>
      <button @click="sumbit" style="background-color: rgb(250, 142, 0);color: aliceblue;">提交</button>
      <button v-show="isshow" @click="answerShow = true"
        style="background-color: rgb(238, 190, 79);color: rgb(255, 255, 255);">查看答案</button>
    </div>
  </div>
</template>

2、script

<script>
export default {
  data() {
    return {
      idx: 0,
      allSocre: 0,
      isshow: false,
      answerShow: false,
      ismultipleAnswer: [],
      question: [
        {
          id: 1,
          ismultiple: false,
          name: '十八大何时召开的?',
          answer: '2012年11月8日',
          score: 2,
          option: [
            { id: 1, name: '2012年11月8日', checked: false, letter: 'A' },
            { id: 2, name: '2012年11月15日', checked: false, letter: 'B' },
            { id: 3, name: '2012年12月18日', checked: false, letter: 'C' },
          ],
        },
        {
          id: 2,
          ismultiple: false,
          name: '你喜欢吃什么?',
          answer: 'C',
          score: 2,
          option: [
            { id: 1, name: '香蕉', checked: false, letter: 'A' },
            { id: 2, name: '苹果', checked: false, letter: 'B' },
            { id: 3, name: '橘子', checked: false, letter: 'C' },
          ],
        },
        {
          id: 3,
          ismultiple: false,
          name: '你的梦想是什么?',
          answer: 'B',
          score: 2,
          option: [
            { id: 1, name: '当一名程序员', checked: false, letter: 'A' },
            { id: 2, name: '当一名测试员', checked: false, letter: 'B' },
            { id: 3, name: '当一名运维', checked: false, letter: 'C' },
          ],
        },
        {
          id: 4,
          ismultiple: true, //是否多选
          name: '这是一题多选吗?',
          answer: 'BC',
          score: 2,
          option: [ //选项
            { id: 1, name: '不是', checked: false, letter: 'A' },
            { id: 2, name: '是的', checked: false, letter: 'B' },
            { id: 3, name: '是的', checked: false, letter: 'C' },
          ],
        },
        {
          id: 5,
          ismultiple: true, //是否多选
          name: '是多选吧?',
          answer: 'ABC',
          score: 2,
          option: [ //选项
            { id: 1, name: '是的', checked: false, letter: 'A' },
            { id: 2, name: '是的', checked: false, letter: 'B' },
            { id: 3, name: '是的', checked: false, letter: 'C' },
          ],
        },
      ]
    }
  },
  methods: {
    next () {
      this.idx++
    },
    back () {
      this.idx--
    },
    handleCilck (info) {
      let question = this.question[this.idx]  //每题选项
      let option = this.question[this.idx].option //每一题题目的选项

      //选中添加样式
      option.forEach(item => {
        if (item.id == info.id) {  //如果选中的与数据里面的相等就改变他的样式
          item.checked = !item.checked  // 是否选中,取反 
        } else if (!question.ismultiple) {  //如果不是多选 只能选中一个 其他的都为false
          item.checked = false
        }
      });


      let isAnswer = info.letter //选中的答案
      let answer = this.question[this.idx].answer //题目中的答案

      //如果是多选
      if (question.ismultiple) {
        this.ismultipleAnswer = []
        option.forEach(item => {
          if (item.checked) { //将选中的push到 ismultipleAnswer 数组中
            this.ismultipleAnswer.push(item.letter)
          }
        });
        isAnswer = this.ismultipleAnswer.join('')  //将ismultipleAnswer转为字符串 下面与答案比较
      }


      console.log('选中的答案', isAnswer);
      console.log('题目的答案', answer);


      //判断是否选正确,计算分数

      if (isAnswer == answer) { // 如果选的答案与题目答案相等,isOk 说明选对了
        this.question[this.idx].isOk = true
      } else {
        this.question[this.idx].isOk = false
      }

    },

    // 提交计算分数
    sumbit () {
      this.allSocre = 0  //每次计算总分先清0,,在计算
      let result = []  //定义选中的个数
      this.question.forEach(item => {
        //返回是否选中的数组
        let selsetArr = item.option.map(val => {
          if (val.checked) {
            return val.checked //map最终返回一个数组,返回 checked 的数组
          }
        })
        console.log('selsetArr', selsetArr);
        //这边是否包含true,包含 true 就push到result中
        const isTrue = selsetArr.includes(true)  //如果包含返回true,否则返回false
        //这里判断一下,如果 isTrue 是 true,说明包含true 就说明选了
        if (isTrue) {
          result.push(isTrue)  //如果选了,就push到 result 中
        }

        if (item.isOk) { //如果isOK 为 true 说明选了,计算分数
          this.allSocre += item.score
        }
      })
      //用选中 result 的长度  与 题目的长度比较 是否相当 不等就没选完
      if (result.length < this.question.length) {
        alert('还有题目没做呢')
        return
      }

      setTimeout(() => {
        alert('获得分数:' + this.allSocre)
        this.isshow = true
      }, 100);

    }
  }
}
</script>

3、css

<style lang="less" scoped>
.question {
  border-radius: 10px;
  color: #515152;
  font-size: 16px;
  padding: 10px 20px;
  margin: 50px 10px 0;
}
.btn-box {
  display: flex;
  justify-content: center;
  align-items: center;
}

button {
  margin-top: 15px;
  margin-right: 10px;
  outline: none;
  background-color: rgb(255, 153, 98);
  border: 0;
  padding: 10px;
  color: rgb(61, 61, 61);
  border-radius: 5px;
}

button:active {
  background-color: rgba(248, 161, 121, 0.664);
}

.title {
  color: black;
  font-weight: 600;
  font-size: 18px;
  height: 30px;
  line-height: 30px;
}

.list {
  margin-top: 10px;
  padding: 10px 5px;
  font-size: 16px;
  border: 1px #eee solid;
  border-radius: 10px;
}

.bgc {
  color: #296ef0;
  background: rgba(41, 110, 240, 0.12);
  border: 1px solid rgba(41, 110, 240, 0.8);
}

.answer {
  color: brown;
  font-size: 16px;
  margin-left: 20px;
}

.select {
  font-size: 18px;
  color: rgb(243, 25, 25);
}
</style>

 

posted @ 2022-07-19 15:04  ℡北瞳少年、  阅读(1427)  评论(0编辑  收藏  举报