基于vue2实现简单的答题组件
更新时间:2024年12月17日 15:02:09 作者:小马超会养兔子
这篇文章主要为大家详细介绍了如何基于vue2实现简单的答题组件,点击正确的选项,该选项背景变绿色;点击错误的选项,该选项背景变红色,有需要的可以参考下
需求
实现一个答题组件,点击正确的选项,该选项背景变绿色;点击错误的选项,该选项背景变红色。不管点击了什么选项,延迟一秒后切换下一题。
每次出题,从题库中选随机选择一道用户此次进入这个页面后还没有做过的题目,如果此次进入这个页面把所有题都做了,则重置,重新开始随机选题。
页面结构
<div class="question"> {{questions[selectedQuestionIndex].question}} </div> <div class="choices"> <div class="choice" v-for="(item, index) in questions[selectedQuestionIndex].choices" :key="item.content" // 当点击了当前的选项,则开始处理背景颜色 :style="{ background: selectedChoiceIndex === index ? feedbackColor : '' }" // 用来显示点击之后的背景颜色 @click="handleChoice(index)" > <span>{{item.index}}</span> <span>{{item.content}}</span> </div> </div>
数据结构
data() { return { selectedQuestionIndex: 0, // 当前显示的问题的索引 selectedChoiceIndex: null, // 记录用户当前选择的选项索引 feedbackColor: '', // 记录选项的反馈颜色 answeredQuestions: new Set(), // 已回答题目索引 questions: [ // 题库 // 1 { question: '下列哪一项不是森林生态系统服务的一部分?', choices: [ { index: 'A: ', content: '氧气生产' }, { index: 'B: ', content: '水土保持' }, { index: 'C: ', content: '提供化石燃料' }, { index: 'D: ', content: '生物多样性维持' }, ], correctChoiceIndex: 2 }, // 2 { question: '碳汇是指什么?', choices: [ { index: 'A: ', content: '大量排放二氧化碳的地方' }, { index: 'B: ', content: '能够吸收并储存二氧化碳的自然系统' }, { index: 'C: ', content: '一种工业过程,用于减少温室气体' }, { index: 'D: ', content: '用于监测大气中二氧化碳水平的技术' }, ], correctChoiceIndex: 1 }, ] }; },
方法解析
有三个方法:
handleChoice
:根据用户的选择决定显示什么背景颜色;切换下一题nextQuestion
:决定下一题选哪一道;重置选择状态和选项背景颜色resetQuiz
:重新开始测试
handleChoice(choiceIndex) { // 判断是否答对 const currentQuestion = this.questions[this.selectedQuestionIndex]; // 获取当前问题 // 判断用户点击的是否是正确选项,计算对应的背景颜色 if (choiceIndex === currentQuestion.correctChoiceIndex) { this.feedbackColor = '#adce74'; // 绿色表示答对 } else { this.feedbackColor = '#ea6458'; // 红色表示答错 } // 设置选中选项索引 // 一旦selectedChoiceIndex有值了,那么页面上就会渲染背景颜色 this.selectedChoiceIndex = choiceIndex; // 延迟一段时间切换到下一题 setTimeout(() => { this.nextQuestion(); }, 1000); // 延迟1秒 },
nextQuestion() { // 将当前题目加入已回答集合 this.answeredQuestions.add(this.selectedQuestionIndex); // 筛选未回答的题目索引 const unansweredIndexes = this.questions .map((_, index) => index) // 得到一个全是问题编号的数组 .filter(index => !this.answeredQuestions.has(index)); // 过滤出不在answeredQuestions里面的问题的序号 if (unansweredIndexes.length > 0) { // 随机选取一道未回答的题目 const randomIndex = Math.floor(Math.random() * unansweredIndexes.length); this.selectedQuestionIndex = unansweredIndexes[randomIndex]; } else { // 如果没有未回答的题目,重置已回答集合并重新开始 this.answeredQuestions.clear(); this.resetQuiz(); } // 重置选中状态 this.selectedChoiceIndex = null; this.feedbackColor = ''; },
resetQuiz() { // 重新随机选择一个题目 this.selectedQuestionIndex = Math.floor(Math.random() * this.questions.length); }
组件代码
<template> <div class="question-container"> <div class="question"> {{questions[selectedQuestionIndex].question}} </div> <div class="choices"> <div class="choice" v-for="(item, index) in questions[selectedQuestionIndex].choices" :key="item.content" :style="{ background: selectedChoiceIndex === index ? feedbackColor : '' }" @click="handleChoice(index)" > <span>{{item.index}}</span> <span>{{item.content}}</span> </div> </div> </div> </template> <script> import {mapMutations} from "vuex"; export default { name: "questionDetail", data() { return { selectedQuestionIndex: 0, selectedChoiceIndex: null, // 记录用户当前选择的选项索引 feedbackColor: '', // 记录选项的反馈颜色 answeredQuestions: new Set(), // 已回答题目索引 questions: [ // 1 { question: '下列哪一项不是森林生态系统服务的一部分?', choices: [ { index: 'A: ', content: '氧气生产' }, { index: 'B: ', content: '水土保持' }, { index: 'C: ', content: '提供化石燃料' }, { index: 'D: ', content: '生物多样性维持' }, ], correctChoiceIndex: 2 }, // 2 { question: '碳汇是指什么?', choices: [ { index: 'A: ', content: '大量排放二氧化碳的地方' }, { index: 'B: ', content: '能够吸收并储存二氧化碳的自然系统' }, { index: 'C: ', content: '一种工业过程,用于减少温室气体' }, { index: 'D: ', content: '用于监测大气中二氧化碳水平的技术' }, ], correctChoiceIndex: 1 }, ] }; }, methods: { ...mapMutations(['addQuestion']), handleChoice(choiceIndex) { // 判断是否答对 const currentQuestion = this.questions[this.selectedQuestionIndex]; if (choiceIndex === currentQuestion.correctChoiceIndex) { this.feedbackColor = '#adce74'; // 绿色表示答对 this.addQuestion(); } else { this.feedbackColor = '#ea6458'; // 红色表示答错 } // 设置选中选项索引 this.selectedChoiceIndex = choiceIndex; // 延迟一段时间切换到下一题 setTimeout(() => { this.nextQuestion(); }, 1000); // 延迟1秒 }, nextQuestion() { // 将当前题目加入已回答集合 this.answeredQuestions.add(this.selectedQuestionIndex); // 筛选未回答的题目索引 const unansweredIndexes = this.questions .map((_, index) => index) .filter(index => !this.answeredQuestions.has(index)); if (unansweredIndexes.length > 0) { // 随机选取一道未回答的题目 const randomIndex = Math.floor(Math.random() * unansweredIndexes.length); this.selectedQuestionIndex = unansweredIndexes[randomIndex]; } else { // 如果没有未回答的题目,重置已回答集合并重新开始 this.answeredQuestions.clear(); this.resetQuiz(); } // 重置选中状态 this.selectedChoiceIndex = null; this.feedbackColor = ''; }, resetQuiz() { // 重新随机选择一个题目 this.selectedQuestionIndex = Math.floor(Math.random() * this.questions.length); } } }; </script> <style scoped lang="scss"> .question-container { width: 98%; height: calc(100vh - 210px); margin-top: 15px; padding: 0 15px 0 15px; //border: 1px red solid; overflow: auto; .question { font-family: 'SanJinSong-Cu', serif; color: #7c9a92; font-size: 35px; } .choices { margin-top: 30px; display: flex; flex-direction: column; gap: 15px; .choice { box-sizing: border-box; padding: 10px 20px; color: white; font-family: 'SanJinSong-Xi', serif; font-size: 25px; width: 100%; min-height: 80px; display: flex; align-items: center; border-radius: 8px; background: linear-gradient(to right, #1F6D5E, #43D6B9); cursor: pointer; transition: background 0.3s ease; } } } </style>
效果演示
到此这篇关于基于vue2实现简单的答题组件的文章就介绍到这了,更多相关vue答题组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
前端Vue设置cookie、删除cookie,获取cookie方式
这篇文章主要介绍了前端Vue设置cookie、删除cookie,获取cookie方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-10-10一步步教你搭建VUE+VScode+elementUI开发环境
这篇文章主要给大家介绍了关于搭建VUE+VScode+elementUI开发环境的相关资料,近期被配置环境的事情弄得整个人都要炸了,现在整理如下,希望有相同需求的朋友可以不用走弯路,需要的朋友可以参考下2023-07-07vue前端实现导出页面为pdf(分页导出、不分页导出及分模块导出)
在实际应用中可能用户希望将系统中一个页面展示的所有数据报表,用PDF的文件格式下载下来,以便于其他用途,这篇文章主要给大家介绍了关于vue前端实现导出页面为pdf(分页导出、不分页导出及分模块导出)的相关资料,需要的朋友可以参考下2024-06-06
最新评论