Create a Magic 8 Ball App with Vue 3 and JavaScript

John Au-Yeung - Jan 17 '21 - - Dev Community

Check out my books on Amazon at https://www.amazon.com/John-Au-Yeung/e/B08FT5NT62

Subscribe to my email list now at http://jauyeung.net/subscribe/

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a magic 8 ball app with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli
Enter fullscreen mode Exit fullscreen mode

with NPM or:

yarn global add @vue/cli
Enter fullscreen mode Exit fullscreen mode

with Yarn.

Then we run:

vue create 8-ball
Enter fullscreen mode Exit fullscreen mode

and select all the default options to create the project.

Create the Magic 8 Ball

To create the magic 8 ball app, we write:

<template>
  <form @submit.prevent="getAnswer">
    <div>
      <label>question</label>
      <input v-model="question" />
    </div>
    <button type="submit">get answer</button>
  </form>
  <div class="circle">
    <p>{{ answer }}</p>
  </div>
</template>

<script>
const answers = [
  "It is certain",
  "It is decidedly so",
  "Without a doubt",
  "Yes - definitely",
  "You may rely on it",
  "As I see it, yes",
  "Most likely",
  "Outlook good",
  "Yes",
  "Signs point to yes",
  "Don't count on it",
  "My reply is no",
  "My sources say no",
  "Outlook not so good",
  "Very doubtful",
  "Reply hazy, try again",
  "Ask again later",
  "Better not tell you now",
  "Cannot predict now",
  "Concentrate and ask again",
];
export default {
  name: "App",
  data() {
    return {
      question: "",
      answer: "",
    };
  },
  methods: {
    getAnswer() {
      if (!this.question) {
        return;
      }
      const index = Math.floor(Math.random() * answers.length);
      this.answer = answers[index];
    },
  },
};
</script>

<style scoped>
.circle {
  border: 1px solid black;
  border-radius: 50%;
  width: 150px;
  height: 150px;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>



Enter fullscreen mode Exit fullscreen mode

We have a form with a text input to let us enter a question into the box.

We bind the inputted value to the question reactive property with v-model .

And we listen to the submit event on the form with the @submit directive.

prevent lets us prevent server-side submission and do client-side submission instead.

Below that we have a div with class circle to create the 8 ball.

We’ll make it a circle and center the answer text inside in the style tag.

Next, we have the answers array with the standard answers for the magic 8 ball.

In the data method, we return an object with the initial values of the question and answer reactive properties.

The getAnswer method lets us get the value of the answer reactive property from the answers array by generating a random index to get the answer.

Before that, we check if we entered a question or not.

In the style tag, we make the div a circle by setting the border-radius and the border for the circle.

We also set the width and height to be the same to make it a circle.

display is set to flex so we can use justify-content to center align the text horizontally.

And we center align the text vertically with align-items .

Conclusion

We can create a magic 8 ball app easily with Vue 3 and JavaScript.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .