Quick Summary

This comprehensive blog tutorial briefly covers how to build a Vue quiz app. We will walk you through setting up your project, organizing reusable components, managing quiz data, and implementing interactive logic. By the end of this guide, you will be able to develop dynamic quiz applications using Vue.js.

Table of Contents

Tutorial Goal: How to Develop Frontend Quiz App using VueJS

One of the biggest challenges developers face after learning a framework like Vue.js is bridging the gap between theory and application. Understanding syntax is one thing, but applying that knowledge to create structured, responsive, and maintainable applications is where the real test begins.

This is where developing a Vue quiz app comes into the picture. It provides lightweight components and makes development easier with dynamic rendering, prop drilling, and conditional logic.

In this blog, we will guide you step-by-step through building a fully functional frontend development quiz app using Vue.js, complete with question navigation, scoring, and smooth user interaction. Let’s start creating a dynamic and compelling Vue.js quiz app.

How to Build Vue Quiz App: A Step-by-Step Guide

To get started, we will first create a new VueJS project. It will give you a clean slate to build upon and organize our app’s components and features effectively.

Step 1: Create VueJS app

Here, we will be using Vue 2. Run the below command to create the VueJs app.

Copy Text
vue create quiz-app

You will get preview like this-

Create-VueJS-app

Now, with the help of the following command navigate to the directory and run the server.

Copy Text
cd quiz-add
npm run serve 

The localhost will display the default screen as shown below.

default screen

Step 2: Create User Interface

Every Vue component consists of three sections:

  • < template >: Contains the HTML structure of the component.
  • < script >: Holds the JavaScript logic, such as data, methods, and event handling.
  • < style >: Defines the CSS styles scoped to the component (optional but common).

Explanation of Component Logic
The component includes two core methods that handle critical aspects of the quiz functionality. These methods are essential for managing the user’s progress, calculating the score, and ensuring a smooth flow through the quiz experience. Let’s break down each of them:

  • handleQuizCompleted()
  • This method receives the user’s score from the Quiz component via a custom event named quiz-completed. It updates the local state property this.score with the received value.

  • updateQuiz()

This method increments the quizKey data property. Updating this key forces the Quiz component to re-render. It’s triggered by the reload event emitted from the CustomModal component.

Want to optimize your Vue app into an interactive and high-performance quiz app?

Hire vuejs developers from us to help you turn your concept into a fully functional app!

Step 3: Create Components

We are moving ahead with our tutorial on developing a front-end quiz app using VueJS. Next, we will start with our components: the Quiz Component and the CustomModal Component.

CustomModal.vue
The file CustomModal.vue will consist of the UI and logic code of the modal. Refer to the code below.

Copy Text

<template>
 <transition name="modal">
   <div class="modal-mask">
     <div class="modal-wrapper">
       <div class="modal-container"
         <div class="modal-header">
           <h2>{{ header }}</h2>
           <h3>{{ subheader }}</h3>
         </div>
 
         <div class="modal-body">
           <div id="score">
             You answered
             <span class="highlight">
               {{
                 Math.floor(
                   (score.correctlyAnsweredQuestions / score.allQuestions) *
                     100
                 )
               }}
               % correctly!
             </span>
             Answered
             <span class="highlight">
               {{ score.correctlyAnsweredQuestions }} out of
               {{ score.allQuestions }}
             </span>
             questions.
           </div>
         </div>
 
         <div class="modal-footer">
           <button
             id="play-again"
             class="button-footer"
             @click="$emit('reload')"
           >
             Play Again
           </button>
           <button
             id="close-button"
             class="button-footer"
             @click="$emit('close')"
           >
             Close
           </button>
         </div>
       </div>
     </div>
   </div>
 </transition>
</template>
 
<script>
export default {
 props: {
   header: String,
   subheader: String,
   score: Object,
 },
};
</script>

Explanation:

  • The score prop contains how many questions the user answered correctly and also contains the total number of questions.
  • We use the score prop received from the Quiz component’s custom events. The modal-footer will have two buttons emitting custom events to reload and close the modal.

Step 4: Quiz.vue

Copy Text

<template>
 <div  class="container">
   <div class="correctAnswers">
     You have
     <strong>{{ correctAnswers }} correct {{ pluralizeAnswer }}!</strong>
   </div>
   <div class="correctAnswers">
     Currently at question {{ index + 1 }} of {{ questions.length }}
   </div>
 
   <h2 v-html="loading ? 'Loading...' : currentQuestion.question" ></h2>
   <!-- Only first question is displayed -->
   <form v-if="currentQuestion">
     <button
       v-for="answer in currentQuestion.answers"
       :index="currentQuestion.key"
       :key="answer"
       v-html="answer"
       @click.prevent="handleClick"
     ></button>
   </form>
 </div>
</template>



Explanation:

  • “loading ? ‘Loading…’ : currentQuestion.question” will check the loading property and based on it will decide ‘Loading…’ or the currentQuestion.
  • The answer of every question will be stored in the array answers. So, we will loop the answers with the help of ‘v-for’ and display every answer as the button element. With that, v-html=”answer” will display the answer on the button.
  • The logic will be executed by handleClick that we will see later in the script part.

Here’s the logic part of the Quiz component. Let’s pick a method one at a time and see what the logic is about.

Step 5: Fetch Questions

The prop ‘questions’ is initialized with an empty array. When ‘loading’ is true, we will fetch the questions using Trivia API, and when the component mounts, we will push them to the array. Here, five questions will be fetched every time an API call is made.

Copy Text
async fetchQuestions() {
     this.loading = true;
     //fetching questions from API
     let response = await fetch(
       "https://opentdb.com/api.php?amount=5&category=21&type=multiple"
     );
     let index = 0; //To identify single answer
     let data = await response.json();
     let questions = data.results.map((question) => {
       question.answers = [
         question.correct_answer,
         ...question.incorrect_answers,
       ];
       //shuffle above array
       for (let i = question.answers.length - 1; i > 0; i--) {
         const j = Math.floor(Math.random() * (i + 1));
         [question.answers[i], question.answers[j]] = [
           question.answers[j],
           question.answers[i],
         ];
       }
       //add right answers and key
       question.rightAnswer = null;
       question.key = index;
       index++;
       return question;
     });
     this.questions = questions;
     this.loading = false;
   },

Step 6: Display Current Question

The computed property currentQuestion() will return the current question at the current index.

Copy Text
currentQuestion() {
     if (this.questions !== []) {
       return this.questions[this.index];
     }
     return null;
   },

Step 7: Count Correct Answers

The code snippet below is to keep count of the correct answers.

Copy Text
correctAnswers() {
     if (this.questions && this.questions.length > 0) {
       let streakCounter = 0;
       this.questions.forEach(function (question) {
         if (!question.rightAnswer) {
           return;
         } else if (question.rightAnswer === true) {
           streakCounter++;
         }
       });
       return streakCounter;
     } else {
       return "--";
     }
   },

Step 8: Calculate score

The logic below will calculate the score. The ‘score()’ will use a reducer array prototype to reduce the current questions array to a n number. It returns the ‘score’ object that we use in the customModal component.

Copy Text
score() {
     if (this.questions !== []) {
       return {
         allQuestions: this.questions.length,
         answeredQuestions: 
     this.questions.reduce((count, currentQuestion) => {
           if (currentQuestion.userAnswer) {
             // userAnswer is set when user has answered a question, no matter if right or wrong
             count++;
           }
           return count;
         }, 0),
         correctlyAnsweredQuestions: this.questions.reduce(
           (count, currentQuestion) => {
             if (currentQuestion.rightAnswer) {
               // rightAnswer is true, if user answered correctly
               count++;
             }
             return count;
           },
           0
         ),
       };
     } else {
       return {
         allQuestions: 0,
         answeredQuestions: 0,
         correctlyAnsweredQuestions: 0,
       };
     }
   },

Step 9: Watcher on Quiz Completion

We will keep a watcher on quizCompleted(). If the quiz is completed, it will emit the event and display the score using this score for the app component.

Copy Text
watch: {
   quizCompleted(completed) {
     completed &&
       setTimeout(() => {
         this.$emit("quiz-completed", this.score);
       }, 3000);
   },
 },

Step 10: Check Correct Answer

To check the correct answer, it will compare userAnswer, the answer given by the user, and correct_answer, the answer given by the API. It further sets ‘.rightAnswer’ and ‘.wrongAnswer’ accordingly and manages the index state for moving on to the next question.

Copy Text
checkCorrectAnswer(e, index) {
     let question = this.questions[index];
     if (question.userAnswer) {
       if (this.index < this.questions.length - 1) {
         setTimeout(
           function () {
             this.index += 1;
           }.bind(this),
           3000
         );
       }
       if (question.userAnswer === question.correct_answer) {
         /* Set class on Button if user answered right, to celebrate right answer with animation joyfulButton */
         e.target.classList.add("rightAnswer");
         /* Set rightAnswer on question to true, computed property can track a streak out of 20 questions */
         this.questions[index].rightAnswer = true;
       } else {
         /* Mark users answer as wrong answer */
         e.target.classList.add("wrongAnswer");
         this.questions[index].rightAnswer = false;
         /* Show right Answer */
         let correctAnswer = this.questions[index].correct_answer;
         let allButtons = document.querySelectorAll(`[index="${index}"]`);
         allButtons.forEach(function (button) {
           if (button.innerHTML === correctAnswer) {
             button.classList.add("showRightAnswer");
           }
         });
       }
     }
   },

Run the server
After running the server, hit the browser and your UI will look something like this

Run the server

When you click the answer, you will know whether your answer is correct or not. The next question will be displayed simultaneously. At the end of the quiz, you will have the score board that will display your correct answer(s).

Conclusion

Developing a quiz app with Vue js is creating an app that goes beyond the basics. From handling component structure and state management to implementing dynamic logic and external API integration, this project highlights Vue’s core concepts in a practical, engaging way.

Whether you are learning Vue to improve your skills or planning to launch a quiz or survey app for your business, Vue.js gives you the tools to move fast and build smart. And if you want to make sure your app is fast, scalable, and looks great, teaming up with a trusted Vue.js development company can help you implement that app without any usual headaches.

Frequently Asked Questions (FAQs)

One of the most effective ways to learn Vue.js is by building small, focused applications like a quiz app. It covers essential concepts, such as component creation, data binding, event handling, and state management.

You can use fetch() or Axios to retrieve quiz data from public APIs like the Open Trivia Database. This approach will help you simulate real-world API consumption and teaches you how to handle asynchronous data in Vue using lifecycle hooks and state updates.

You can absolutely enhance it by adding user authentication, result tracking with a backend, Vue Router for multi-page navigation, or Vuex for centralized state management. These additions make the app more production-ready and scalable.

Ready to Build Your Own Vue Quiz App?

Let our Vue experts guide you through the process and help you create and optimize a dynamic, fully functional quiz app from scratch.

Contact Us

Build Your Agile Team

Hire Skilled Developer From Us

solutions@bacancy.com

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.