vue+vant制作一个做题页面(包含选择题,判断题,填空题,简答题)

简介: vue+vant制作一个做题页面(包含选择题,判断题,填空题,简答题)

vue+vant制作一个做题页面(包含选择题,判断题,填空题,简答题)

本文讲解如何结合vue+vant制作一个做题页面里面包含选择题,判断题,填空题,简答题,还包含计算成绩的功能。

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

代码讲解

效果展示

完整代码如下:

<template>
  <div>
    <!-- 标题栏 -->
    <van-nav-bar title="题目测试" left-text="返回" left-arrow @click-left="onClickLeft" />
    <!-- 题目列表 -->
    <van-list v-if="questions.length > 0">
      <div class="question-card" v-for="(question, index) in questions" :key="question.id">
        <van-card
              :title="index + 1 + '. ' + question.content"
              :class="{ 'bg-red': showAnswer[question.id] && selectedAnswers[question.id] !== question.answer }">
          <!-- 根据题目类型进行渲染 -->
          <template v-if="question.questionType === '选择题'" #desc>
            <van-radio-group v-model="selectedAnswers[question.id]">
              <van-radio :name="'A'">A.{{ question.optionA }}</van-radio>
              <van-radio :name="'B'">B.{{ question.optionB }}</van-radio>
              <van-radio :name="'C'">C.{{ question.optionC }}</van-radio>
              <van-radio :name="'D'">D.{{ question.optionD }}</van-radio>
            </van-radio-group>
            <!-- 显示正确答案 -->
        <p class="answer" v-if="question && showAnswer[question.id]">正确答案:<span class="correct">{{ question.answer }}</span></p>
          </template>
          <template v-else-if="question.questionType === '判断题'" #desc>
            <van-radio-group v-model="selectedAnswers[question.id]" :direction="isVertical ? 'vertical' : 'horizontal'">
              <van-radio :name="'true'">正确</van-radio>
              <van-radio :name="'false'">错误</van-radio>
            </van-radio-group>
            <!-- 显示正确答案 -->
        <p class="answer" v-if="question && showAnswer[question.id]">正确答案:<span class="correct">{{ question.answer }}</span></p>
          </template>
          <template v-else-if="question.questionType === '简答题'" #desc>
            <van-field v-model="selectedAnswers[question.id]" :rows="3" placeholder="请输入简答题答案" />
            <!-- 显示正确答案 -->
        <p class="answer" v-if="question && showAnswer[question.id]">正确答案:<span class="correct">{{ question.answer }}</span></p>
          </template>
          <template v-else-if="question.questionType === '填空题'" #desc>
            <van-field
                   v-model="selectedAnswers[question.id]"
                   label-width="80px"
                   placeholder="请输入填空题答案">
              <template #label>请填写答案:</template>
            </van-field>
            <!-- 显示正确答案 -->
        <p class="answer" v-if="question && showAnswer[question.id]">正确答案:<span class="correct">{{ question.answer }}</span></p>
          </template>                 
        </van-card>
      </div>
    </van-list>
    <!-- 无数据占位符 -->
    <van-empty v-else />
    <!-- 提交答案按钮 -->
    <van-button ref="submitButton" block type="primary" :disabled="isSubmitting" @click="onSubmit">{{ submitBtnText }}</van-button>
  </div>
</template>
<script>
  import axios from "axios";
  import { showDialog } from 'vant';
  export default {
    data() {
      return {
        questions: [], // 题目列表
        selectedAnswers: {}, // 用户选择的答案
        showAnswer: {}, // 是否显示答案
        isVertical: false, // 是否垂直布局选项(主要用于选择题)
        currentQuestionIndex: 0, // 当前问题的索引
        totalScore: 0, // 总分数
        isSubmitting: false, // 是否正在提交答案
      };
    },
    computed: {
      submitBtnText() {
        return this.isSubmitting ? '正在提交' : '提交'
      }
    },
    methods: {
      // 返回按钮点击事件处理函数
      onClickLeft() {
        this.$router.push("/my");
      },
      // 提交答案的代码
      onSubmit() {
        let totalCount = Object.keys(this.selectedAnswers).length;
        let correctCount = 0;
        let score = 0;
        // 禁用提交按钮
        this.isSubmitting = true
        // 计算总得分
        for (const question of this.questions) {
          const userAnswer = this.selectedAnswers[question.id];
          if (userAnswer === question.answer) {
            correctCount++;
            score += question.score;
          }
          // 显示正确答案
          this.showAnswer[question.id] = true;
        }
        this.totalScore = score;
        // 使用vant-ui组件弹出对话框显示结果
    const message = `你选择了 ${totalCount} 道题,答对了 ${correctCount} 道题。总得分:${this.totalScore} 分。`;
    showDialog({
      title: "考试结束啦>_<",
      message: message,
    }).then(() => {
      // on close
    });
    // 禁用提交按钮
    this.isSubmitting = true
    // 显示正确答案
    for (const question of this.questions) {
      this.showAnswer[question.id] = true;
    }
    // console.log("正确答案集合")
    // for (let i = 0; i < this.questions.length; ++ i){
    //   console.log(this.questions[i].answer)
    // }
    console.log("用户选择的正确答案集合")
    console.log(this.selectedAnswers)
  },
  // 获取问题分数
  getQuestionScore(questionId) {
    const userAnswer = this.selectedAnswers[questionId];
    const question = this.questions.find((q) => q.id === questionId);
    return userAnswer === question.answer ? question.score : 0;
  },
  // 显示当前问题
  showQuestion() {
    // 获取当前问题
    const question = this.questions[this.currentQuestionIndex];
    // 根据题目类型渲染问题
    switch (question.questionType) {
      case "选择题":
        this.isVertical = false;
        break;
      case "判断题":
        this.isVertical = true;
        break;
    }
    // 显示问题并将提交按钮重新启用
    this.$refs.submitButton.disable = false;
  },
  },
  mounted() {
  // 获取题目列表
  axios
  .get("http://localhost:8083/questions")
  .then((res) => {
  this.questions = res.data.data;
      // 对问题数据进行按题目类型排序
      this.questions.sort((a, b) => {
        const typeOrder = { "选择题": 0, "判断题": 1, "填空题": 2, "简答题": 3 };
        return typeOrder[a.questionType] - typeOrder[b.questionType];
      });
      // 显示第一个问题
      this.showQuestion();
    })
    .catch((error) => {
      console.log(error);
    });
  },
  };
</script>
<style>
  .answer {
  color: red;
  margin-bottom: 0;
  }
  .correct {
  color: green;
  }
</style>

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

相关文章
|
12月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
872 2
|
11月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
745 137
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
1617 0
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
963 1
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
668 0
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
945 1
|
存储 前端开发 JavaScript
为什么我不再用Vue,改用React?
当我走进现代前端开发行业的时候,我做了一个每位开发人员都要做的决策:选择一个合适的框架。当时正逢 jQuery 被淘汰,前端开发者们不再用它编写难看的、非结构化的老式 JavaScript 程序了。
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1621 4
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
1933 78