How to make a Star Wars Random Quote App using Vue
Tags: tutorial, programming, beginners, vue
Published: 2021-02-13 19:08:49

## 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](https://dev-to-uploads.s3.amazonaws.com/i/j025t37kqhz3k3f00s5o.png)

## Prerequisites
For this tutorial we will use: 
* [Node.js and Npm](https://nodejs.org/en/download/)
* [Vue.js](https://vuejs.org/v2/guide/installation.html)
* [Star Wars Quote API](http://swquotesapi.digitaljedi.dk/index.html)
* Your favorite IDE ( I use [Visual Studio Code](https://code.visualstudio.com/))

## Create a new Vue app
Go to the place where you want to create your project. Open a terminal and type the following:

```console
vue create starwars-app
```
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](https://dev-to-uploads.s3.amazonaws.com/i/pcb1vwobks70o62k2g67.png)

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

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

<script>

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

<style>
</style>
```

## 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.

```vue
<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>
```
## Adding functionality

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

```vue
<script>
export default {
  name: 'App',
  data: function() {
    return {
      quote: ""
    }
  }
</script>
```
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](https://www.w3schools.com/js/js_api_fetch.asp)

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

```vue
<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>
```
We use the `axios.get` to make a request to the Star Wars quote API. This will return a response.

```json
{
"id": 5,
"content": "Chewie, we're home. - Han Solo"
}
``` 
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.

```vue
<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>
```

## Styling

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

```css
<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>
```
## 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](https://twitter.com/AlexanderGekov) and [Youtube](https://www.youtube.com/channel/UCAARceUUB_X6xsgeRBRg16A) for more awesome tutorials.

**May the Force be with you!** 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ydrv09hbsa9o5mddmvzn.jpg)