继昨天完成的Quiz App(原生JS版)後,这次要来看的是Vue版:Demo Link | CodePen(原生JS版)
Vue版和原生JS版本不同的地方
Vue档案部分有三个
src/views/QuizApp.vue
<template>
<home-btn />
<main
class="
bg-gradient-to-tl
from-blue-200
via-yellow-100
to-gray-300
w-[100vw]
flex
justify-center
items-center
overflow-hidden
mr-0
"
>
<div
class="bg-white rounded-lg w-[600px] drop-shadow-lg"
id="quiz-container"
>
<div id="quiz-header" class="p-12 flex flex-col justify-around">
<questions
// 答题数小於题库长度时才显示子元件
v-if="quizAnswered < quizData.length"
// 将题库quizData送进子元件
:quizData="quizData"
// 将答题数送进子元件
:quizAnswered="quizAnswered"
// 将属性check-answer送进子元件,当子元件emit上来时,便会触发函式checkAnswer
@check-answer="checkAnswer"
/>
// 子元件questions不显示时便显示result
<result v-else :score="score" />
<button
id="Reset"
class="
bg-purple-600
hover:bg-purple-800
text-white
tracking-wide
font-normal
w-[15%]
cursor-pointer
mt-3
rounded-3xl
"
// 当答题数等於题库阵列长度时,才显示reset按钮
v-if="quizAnswered === quizData.length"
// 点击按钮,触发reset,回到第一题。
@click.prevent="reset"
>
Reset
</button>
</div>
</div>
</main>
</template>
<script>
import homeBtn from '../components/HomeBtn.vue'
import Questions from '../components/quiz-app/Questions.vue'
import Result from '../components/quiz-app/Result.vue'
import { ref } from 'vue'
export default {
name: '#15. Quiz App',
components: {
homeBtn,
Questions,
Result,
},
setup() {
// 建立题库
const quizData = ref([
{
q: 'Which language runs in a web browser?',
answers: [
{
text: 'Java',
is_correct: false,
},
{
text: 'C',
is_correct: false,
},
{
text: 'Python',
is_correct: false,
},
{
text: 'Javascript',
is_correct: true,
},
],
},
// ...略(共四题)
])
const quizAnswered = ref(0)
const score = ref(0)
// 若选中的answer.is_correct为true,则score + 1
const checkAnswer = (is_correct) => {
if (is_correct) {
score.value++
}
// 判断是否要给分後,进到下一题
quizAnswered.value++
}
// 重设分数与答题数
const reset = () => {
score.value = 0
quizAnswered.value = 0
}
return {
quizData,
quizAnswered,
score,
checkAnswer,
reset,
}
},
}
</script>
src/components/quiz-app/Questions.vue
<template>
<div
class="p-0 flex flex-col"
id="single-question"
// 这里使用v-for遍历题库,将资料渲染进模板中
v-for="(question, index) in quizData"
// 只有目前要作答的题目才会显示
v-show="quizAnswered === index"
:key="question.q"
>
<h2 class="text-center mb-3 text-3xl font-semibold">
// 对照题库资料结构,显示题目
{{ question.q }}
</h2>
<div
class="
text-xl
font-thin
text-center
my-2
hover:bg-gray-100 hover:font-normal
rounded-sm
"
// 按照资料结构,每个题目中还有一个阵列answers,在此也用v-for渲染出来
v-for="answer in question.answers"
:key="answer.text"
// 被选中的答案,会把answer里的is_correct带进函式selectAnswer
@click.prevent="selectAnswer(answer.is_correct)"
>
<div class="cursor-pointer py-3 border-2 rounded-lg">
// 对照题库资料结构,显示答案选项
{{ answer.text }}
</div>
</div>
</div>
<div class="progress mt-2 h-[40px] relative bg-pink-50">
<div
class="bar bg-pink-300 h-[40px] transition-all duration-300"
// 这里运用答题数与题库阵列长度的运算,即时改变style所绑定的width
// 达成进度条显示效果
:style="{ width: `${(quizAnswered / quizData.length) * 100}%` }"
></div>
<div class="status absolute top-[10px] w-full left-0 text-center">
{{ quizAnswered }} out of {{ quizData.length }} quiz answered
</div>
</div>
</template>
<script>
export default {
name: 'Questions',
// 用emits引入父元件的check-answer
emits: ['check-answer'],
// 从父元件引入props资料quizData和quizAnswered
props: {
quizData: {
type: Object,
required: true,
},
quizAnswered: {
type: Number,
required: true,
},
},
setup(props, { emit }) {
// 建立selectAnswer函式,并引入参数is_correct,然後透过emit中的check-answer,将is_correct送到父元件,来执行父元件的checkAnswer函式
const selectAnswer = (is_correct) => {
emit('check-answer', is_correct)
}
return {
selectAnswer
}
},
}
</script>
src/components/quiz-app/Result.vue
Result.vue部分还有一些地方可以优化,之後会再进一步调整。
<template>
<div class="result">
<div class="title">Glad you finish this quiz! </div>
// 这里单纯从父元件取得score,然後渲染进模板中
<div class="desc">Your score is: {{ score }} / 4</div>
</div>
</template>
<script>
export default {
name: 'results',
props: {
score: {
type: Number,
required: true,
}
},
setup() {
},
}
</script>
写文章写一半发现忘了时间,PO完这篇已经过了6秒,今年铁人赛没挑战成功...Orz
没关系继续努力!
<<: 【Day 02】- 网路爬虫环境设定(Python、pipenv、Vscode)
>>: Day 2 - Home Lab 事前准备 - 安装篇
前言 初次参加铁人赛,开赛第一天,先放轻松暖个身,把前辈的文章看过一遍吧! 相关文章 Mike Fa...
2.1基本组译器功能 2.1.1简易SIC组译器 组译器的两阶段处理 1.扫描原始程序中的标记,并计...
想知道我们在使用滑鼠操作电脑时作业系统在背後做了什麽事情吗? 又或者为什麽我们在写 C 语言时,老师...
今天一起来认识二元树的三种遍历方式吧! 但是别急!我们先来认识二元搜寻树BST的定义! 二元搜寻树是...
今天要来跟各位一起解析 QnA Maker Bot,以下简称 QA Bot。 今天是参考 官方范例程...