DEV Community

Cover image for How to make a Star Wars Random Quote App using Vue
Alexander Gekov
Alexander Gekov

Posted on

How to make a Star Wars Random Quote App using Vue

Introduction

Hello there everyone, I gotta say I really like the Mandalorian TV series. It brings me back to my childhood and I like it so much in fact, that I decided to build a small little project.

The project will display random quotes from the Star Wars universe. It is a great project for beginners who want to learn about Vue and APIs.

Alt Text

Prerequisites

For this tutorial we will use:

Create a new Vue app

Go to the place where you want to create your project. Open a terminal and type the following:

vue create starwars-app
Enter fullscreen mode Exit fullscreen mode

We will select the Vue 2 default option and let it create the project.
When it's done cd into starwars-app and run npm run serve to confirm the project was successfully created. You will see the following:
Alt Text

Open up your IDE and navigate to src/App.vue. Clean it up so it looks like this:

<template>
  <div id="app">
  </div>
</template>

<script>

export default {
  name: 'App'
}
</script>

<style>
</style>
Enter fullscreen mode Exit fullscreen mode

Building the layout

For the structure of our app, we will have a container that will have the star wars logo, our quote, and a refresh button.

<template>
  <div id="app" class="container">
    <div class="logo">
      <img src="https://www.pnglib.com/wp-content/uploads/2020/01/star-wars-logo_5e276b528b103.png" alt="">
    </div>
    <div class="quote">
        {{quote}}
    </div>
    <button @click="fetchQuote" class="reload">
      <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" clip-rule="evenodd"></path></svg>
    </button>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Adding functionality

So we have our structure but let's go on and create our state for the app.

<script>
export default {
  name: 'App',
  data: function() {
    return {
      quote: ""
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

Now we have our quote variable and we can move on to our method.
If you look back at our template you will see that the button has an @click="fetchQuote". That is the click handler for our method. Let's create it now.

For this example we will be using an HTTP request library - axios but you can also use the built-in Fetch API

If you decide to use axios you will want to install it with npm install axios.

<script>
import axios from 'axios'
export default {
  name: 'App',
  data: function() {
    return {
      quote: ""
    }
  },
  methods: {
    fetchQuote(){
      axios.get("http://swquotesapi.digitaljedi.dk/api/SWQuote/RandomStarWarsQuote")
      .then(response => {
        this.quote = response.data.content;
      })
      .catch(error){
        console.log(error.message);
      }
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

We use the axios.get to make a request to the Star Wars quote API. This will return a response.

{
"id": 5,
"content": "Chewie, we're home. - Han Solo"
}
Enter fullscreen mode Exit fullscreen mode

so we can then assign the response.data.content to this.quote.

We will also want to fetch one quote at the beginning so it doesn't stay blank.
For that, we will use the created lifecycle hook and call fetchQuote from there.

<script>
import axios from 'axios'
export default {
  name: 'App',
  data: function() {
    return {
      quote: ""
    }
  },
  created(){
    this.fetchQuote()
  },
  methods: {
    fetchQuote(){
      axios.get("http://swquotesapi.digitaljedi.dk/api/SWQuote/RandomStarWarsQuote")
      .then(response => {
        console.log(response.data)
        this.quote = response.data.content
      })
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

Styling

All that is left is to add some styling and we are done.

<style>
*{
  margin: 0;
  padding: 0;
}
#app{
  background-image: url("https://starwarsblog.starwars.com/wp-content/uploads/2020/04/star-wars-backgrounds-25.jpg");
}
.container{
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
}
.logo img{
  width: 24rem;
}
.quote{
  padding: 2rem;
  border-radius: 0.5rem;
  background-color: rgb(17, 25, 43);
  margin-top: 1.25rem;
  font-weight: 500;
  font-size: 3.75rem;
  line-height: 1;
  color: white;
  max-width: 72rem;
}
.reload{
  background-color: rgba(37, 99, 235, 1);
  padding: 0.5rem;
  border-radius: 50%;
  width: 2.5rem;
  height: 2.5rem;
  margin-top: 2.5rem;
  color: white;
  cursor: pointer;
}
.reload:hover{
  background-color: rgba(29, 78, 216, 1);
}
.reload:focus{
  outline: none
}
</style>
Enter fullscreen mode Exit fullscreen mode

Conclusion

In this tutorial we learned about basic Vue components, Vue lifecycle hooks and utilizing APIs in our application.

If you liked this tutorial be sure to follow me on Twitter and Youtube for more awesome tutorials.

May the Force be with you!

Alt Text

Top comments (1)

Collapse
 
alexandergekov profile image
Alexander Gekov

Link to code can be found here.