基于vue2實(shí)現(xiàn)簡(jiǎn)單的答題組件
需求
實(shí)現(xiàn)一個(gè)答題組件,點(diǎn)擊正確的選項(xiàng),該選項(xiàng)背景變綠色;點(diǎn)擊錯(cuò)誤的選項(xiàng),該選項(xiàng)背景變紅色。不管點(diǎn)擊了什么選項(xiàng),延遲一秒后切換下一題。
每次出題,從題庫(kù)中選隨機(jī)選擇一道用戶此次進(jìn)入這個(gè)頁(yè)面后還沒(méi)有做過(guò)的題目,如果此次進(jìn)入這個(gè)頁(yè)面把所有題都做了,則重置,重新開(kāi)始隨機(jī)選題。
頁(yè)面結(jié)構(gòu)
<div class="question">
{{questions[selectedQuestionIndex].question}}
</div>
<div class="choices">
<div
class="choice"
v-for="(item, index) in questions[selectedQuestionIndex].choices"
:key="item.content"
// 當(dāng)點(diǎn)擊了當(dāng)前的選項(xiàng),則開(kāi)始處理背景顏色
:style="{ background: selectedChoiceIndex === index ? feedbackColor : '' }" // 用來(lái)顯示點(diǎn)擊之后的背景顏色
@click="handleChoice(index)"
>
<span>{{item.index}}</span>
<span>{{item.content}}</span>
</div>
</div>
數(shù)據(jù)結(jié)構(gòu)
data() {
return {
selectedQuestionIndex: 0, // 當(dāng)前顯示的問(wèn)題的索引
selectedChoiceIndex: null, // 記錄用戶當(dāng)前選擇的選項(xiàng)索引
feedbackColor: '', // 記錄選項(xiàng)的反饋顏色
answeredQuestions: new Set(), // 已回答題目索引
questions: [ // 題庫(kù)
// 1
{
question: '下列哪一項(xiàng)不是森林生態(tài)系統(tǒng)服務(wù)的一部分?',
choices: [
{ index: 'A: ', content: '氧氣生產(chǎn)' },
{ index: 'B: ', content: '水土保持' },
{ index: 'C: ', content: '提供化石燃料' },
{ index: 'D: ', content: '生物多樣性維持' },
],
correctChoiceIndex: 2
},
// 2
{
question: '碳匯是指什么?',
choices: [
{ index: 'A: ', content: '大量排放二氧化碳的地方' },
{ index: 'B: ', content: '能夠吸收并儲(chǔ)存二氧化碳的自然系統(tǒng)' },
{ index: 'C: ', content: '一種工業(yè)過(guò)程,用于減少溫室氣體' },
{ index: 'D: ', content: '用于監(jiān)測(cè)大氣中二氧化碳水平的技術(shù)' },
],
correctChoiceIndex: 1
},
]
};
},
方法解析
有三個(gè)方法:
handleChoice:根據(jù)用戶的選擇決定顯示什么背景顏色;切換下一題nextQuestion:決定下一題選哪一道;重置選擇狀態(tài)和選項(xiàng)背景顏色resetQuiz:重新開(kāi)始測(cè)試
handleChoice(choiceIndex) {
// 判斷是否答對(duì)
const currentQuestion = this.questions[this.selectedQuestionIndex]; // 獲取當(dāng)前問(wèn)題
// 判斷用戶點(diǎn)擊的是否是正確選項(xiàng),計(jì)算對(duì)應(yīng)的背景顏色
if (choiceIndex === currentQuestion.correctChoiceIndex) {
this.feedbackColor = '#adce74'; // 綠色表示答對(duì)
} else {
this.feedbackColor = '#ea6458'; // 紅色表示答錯(cuò)
}
// 設(shè)置選中選項(xiàng)索引
// 一旦selectedChoiceIndex有值了,那么頁(yè)面上就會(huì)渲染背景顏色
this.selectedChoiceIndex = choiceIndex;
// 延遲一段時(shí)間切換到下一題
setTimeout(() => {
this.nextQuestion();
}, 1000); // 延遲1秒
},
nextQuestion() {
// 將當(dāng)前題目加入已回答集合
this.answeredQuestions.add(this.selectedQuestionIndex);
// 篩選未回答的題目索引
const unansweredIndexes = this.questions
.map((_, index) => index) // 得到一個(gè)全是問(wèn)題編號(hào)的數(shù)組
.filter(index => !this.answeredQuestions.has(index)); // 過(guò)濾出不在answeredQuestions里面的問(wèn)題的序號(hào)
if (unansweredIndexes.length > 0) {
// 隨機(jī)選取一道未回答的題目
const randomIndex = Math.floor(Math.random() * unansweredIndexes.length);
this.selectedQuestionIndex = unansweredIndexes[randomIndex];
} else {
// 如果沒(méi)有未回答的題目,重置已回答集合并重新開(kāi)始
this.answeredQuestions.clear();
this.resetQuiz();
}
// 重置選中狀態(tài)
this.selectedChoiceIndex = null;
this.feedbackColor = '';
},
resetQuiz() {
// 重新隨機(jī)選擇一個(gè)題目
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, // 記錄用戶當(dāng)前選擇的選項(xiàng)索引
feedbackColor: '', // 記錄選項(xiàng)的反饋顏色
answeredQuestions: new Set(), // 已回答題目索引
questions: [
// 1
{
question: '下列哪一項(xiàng)不是森林生態(tài)系統(tǒng)服務(wù)的一部分?',
choices: [
{ index: 'A: ', content: '氧氣生產(chǎn)' },
{ index: 'B: ', content: '水土保持' },
{ index: 'C: ', content: '提供化石燃料' },
{ index: 'D: ', content: '生物多樣性維持' },
],
correctChoiceIndex: 2
},
// 2
{
question: '碳匯是指什么?',
choices: [
{ index: 'A: ', content: '大量排放二氧化碳的地方' },
{ index: 'B: ', content: '能夠吸收并儲(chǔ)存二氧化碳的自然系統(tǒng)' },
{ index: 'C: ', content: '一種工業(yè)過(guò)程,用于減少溫室氣體' },
{ index: 'D: ', content: '用于監(jiān)測(cè)大氣中二氧化碳水平的技術(shù)' },
],
correctChoiceIndex: 1
},
]
};
},
methods: {
...mapMutations(['addQuestion']),
handleChoice(choiceIndex) {
// 判斷是否答對(duì)
const currentQuestion = this.questions[this.selectedQuestionIndex];
if (choiceIndex === currentQuestion.correctChoiceIndex) {
this.feedbackColor = '#adce74'; // 綠色表示答對(duì)
this.addQuestion();
} else {
this.feedbackColor = '#ea6458'; // 紅色表示答錯(cuò)
}
// 設(shè)置選中選項(xiàng)索引
this.selectedChoiceIndex = choiceIndex;
// 延遲一段時(shí)間切換到下一題
setTimeout(() => {
this.nextQuestion();
}, 1000); // 延遲1秒
},
nextQuestion() {
// 將當(dāng)前題目加入已回答集合
this.answeredQuestions.add(this.selectedQuestionIndex);
// 篩選未回答的題目索引
const unansweredIndexes = this.questions
.map((_, index) => index)
.filter(index => !this.answeredQuestions.has(index));
if (unansweredIndexes.length > 0) {
// 隨機(jī)選取一道未回答的題目
const randomIndex = Math.floor(Math.random() * unansweredIndexes.length);
this.selectedQuestionIndex = unansweredIndexes[randomIndex];
} else {
// 如果沒(méi)有未回答的題目,重置已回答集合并重新開(kāi)始
this.answeredQuestions.clear();
this.resetQuiz();
}
// 重置選中狀態(tài)
this.selectedChoiceIndex = null;
this.feedbackColor = '';
},
resetQuiz() {
// 重新隨機(jī)選擇一個(gè)題目
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>
效果演示

到此這篇關(guān)于基于vue2實(shí)現(xiàn)簡(jiǎn)單的答題組件的文章就介紹到這了,更多相關(guān)vue答題組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue keep-alive實(shí)踐總結(jié)(推薦)
本篇文章主要介紹了Vue keep-alive實(shí)踐總結(jié)(推薦),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
vue彈窗里面使用echarts不顯示的問(wèn)題及解決
這篇文章主要介紹了vue彈窗里面使用echarts不顯示的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
Vue 解決路由過(guò)渡動(dòng)畫(huà)抖動(dòng)問(wèn)題(實(shí)例詳解)
這篇文章主要介紹了Vue 解決路由過(guò)渡動(dòng)畫(huà)抖動(dòng)問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
vue給數(shù)組中對(duì)象排序 sort函數(shù)的用法
這篇文章主要介紹了vue給數(shù)組中對(duì)象排序 sort函數(shù)的用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue3中WatchEffect高級(jí)偵聽(tīng)器的實(shí)現(xiàn)
本文主要介紹了vue3中WatchEffect高級(jí)偵聽(tīng)器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01
vue遞歸組件實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)
這篇文章主要為大家詳細(xì)介紹了vue遞歸組件實(shí)現(xiàn)樹(shù)形結(jié)構(gòu),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-09-09
vue 驗(yàn)證碼界面實(shí)現(xiàn)點(diǎn)擊后標(biāo)灰并設(shè)置div按鈕不可點(diǎn)擊狀態(tài)
今天小編就為大家分享一篇vue 驗(yàn)證碼界面實(shí)現(xiàn)點(diǎn)擊后標(biāo)灰并設(shè)置div按鈕不可點(diǎn)擊狀態(tài),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-10-10
淺談VUE單頁(yè)應(yīng)用首屏加載速度優(yōu)化方案
這篇文章主要介紹了淺談VUE單頁(yè)應(yīng)用首屏加載速度優(yōu)化方案,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08

