今天的內容將延續昨天的實作內容,繼續探討 Vue 實際的應用
以下實作是使用 Composition API 撰寫,將著重講解<script setup>
標籤的程式碼,以及<template>
標籤內有使用到 Vue 語法的地方:
<!-- Question.vue 檔案 -->
<script setup>
import {defineEmits} from "vue"
const emit = defineEmits(["selectOption"])
const emitSelectOption = (isCorrect) => {
emit("selectOption", isCorrect)
}
</script>
<template>
<div class="options-container">
<div
v-for="option in question.options"
:key="option.id"
@click="emitSelectOption(option.isCorrect)"
class="option">
<p class="option-label">{{ option.label }}</p>
<div class="option-value">
<p>{{ option.text }}</p>
</div>
</div>
</div>
</template>
<!-- QuizView.vue 檔案 -->
<script setup>
import quizes from "../data/quizes.json"
import Question from "../components/Question.vue"
const numberOfCorrectAnswers = ref(0)
const onOptionSelected = (isCorrect) => {
if(isCorrect){
numberOfCorrectAnswers.value++
}
currentQuestionIndex.value++
}
</script>
<template>
<div>
<div>
<Question
v-if="!showResults"
:question="quiz.questions[currentQuestionIndex]"
@selectOption="onOptionSelected"
/>
</div>
</div>
</template>
動態Props:使用 v-bind (或簡寫:) 的方式將外層元件的資料內容傳入
表示 Result 元件會從父元件 (QuizView.vue) 接收題目總數和答對數並顯示在畫面上。
<!-- Result.vue 檔案 -->
<script setup>
import { defineProps } from 'vue';
import { RouterLink } from 'vue-router';
const {quizQuestionLength, numberOfCorrectAnswers} = defineProps(["quizQuestionLength",
"numberOfCorrectAnswers"])
</script>
<template>
<div class="result">
<p>Your Results...</p>
<h1>{{ numberOfCorrectAnswers }}/{{ quizQuestionLength }}</h1>
<RouterLink to="/">Go Back</RouterLink>
</div>
<!-- QuizView.vue 檔案 -->
<script setup>
import {useRoute} from "vue-router"
import quizes from "../data/quizes.json"
import Result from "../components/Result.vue"
const route = useRoute()
const quizId = parseInt(route.params.id)
const quiz = quizes.find(q => q.id === quizId)
const currentQuestionIndex = ref(0)
const numberOfCorrectAnswers = ref(0)
const onOptionSelected = (isCorrect) => {
if(isCorrect){
numberOfCorrectAnswers.value++
}
if(quiz.questions.length-1 === currentQuestionIndex.value){
showResults.value = true
}
currentQuestionIndex.value++
}
const showResults = ref(false)
</script>
<template>
<div>
<div>
<Question
v-if="!showResults"
:question="quiz.questions[currentQuestionIndex]"
@selectOption="onOptionSelected"
/>
<Result
v-else
:quizQuestionLength="quiz.questions.length"
:numberOfCorrectAnswers="numberOfCorrectAnswers"
/>
</div>
</div>
</template>
https://www.youtube.com/watch?v=I_xLMmNeLDY