← home ← blog

Getting Started with Vue JS

To say the world is a bit… crazy right now… would be an understatement; with that said, a lot of us could use a distraction and for me, that’s writing and code. If you’ve read my past post, you would have seen my interest in spending 2020 learning and just messing around, so today we’re focusing on something fun; Vue JS1.

VueJS

What Are We Building/Learning?

To kick things off, we’re going to jump into creating a sample project, adding routes to different pages, and some of the basic information to understand how this all ties together - don’t fret though, over the next few posts, we’ll be doing some API integrations, authentication, etc to expand your example application.

In short, when we’re done today, you should have the following completed:

  • Vue JS Project Created
  • Homepage Design & Setup
  • 3 Interior Pages / Routes
  • Several “Components” for shared pieces of code

Installation

To get us started, you can run the following within your terminal to get Vue CLI installed:

# npm install -g @vue/cli

Depending on your system configuration and setup, you might need to run as sudo with the following:

# sudo npm install -g @vue/cli

Note: If you’re in a rush or just want to prototype something rapidly, you can include the following within your code:

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

Create Project

If you’re expecting something complicated, you’d be wrong; you just need to run the following within your terminal:

# vue create lesson-1

Once entered, you should see the following message in your terminal:

Vue CLI v4.2.3
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
  Manually select features

For the time being, please simply hit your enter key to see the following:

Note: There are a lot of options here for manually selected features; Bable, TypeScript, PWA (Progressive Web App), Router, Vuex, CSS Pre-processors, Linter/Formatter, Unit Testing, etc - we’re just not diving into all of those today.

Vue CLI v4.2.3
Failed to check for updates
? Please pick a preset: default (babel, eslint)
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
  Use NPM

Go ahead and hit enter one more time and you’ll see the following (and then a bunch of items installing):

Vue CLI v4.2.3
✨  Creating project in /home/intergalacticmeow/dev/testing/lesson-1.
🗃  Initializing git repository...
⚙️  Installing CLI plugins. This might take a while...

Once 100% completed, you should see something like the following:

⚓  Running completion hooks...

�📄  Generating README.md.

�🎉  Successfully created project lesson-1.
�👉  Get started with the following commands:

 $ cd lesson-1
 $ npm run serve

Note: If you’re not a fan of the terminal and want to use a user interface, you can run the following in your terminal which will open a web page within your browser to help assist with creating a project:

# vue ui

With the project installed, let’s go ahead and change into our directory and install Vue Router so we can add to our code in a moment:

# cd lesson-1
# npm install vue-router

Let’s Get This Started

To get us going, let’s go ahead and add our Vue Router to the code; to do this, open src/main.js which should look like the following:

import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

We need to update this to look like the following:

import Vue from 'vue'
import VueRouter from 'vue-router'
import App from './App.vue'

Vue.use(VueRouter)
Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

This includes two new important lines:

import VueRouter from 'vue-router'

Vue.use(VueRouter)

With this in place, let’s go ahead and run the following:

# npm run serve

Oops, looks like we missed installing something in the environment:

Command vue serve requires a global addon to be installed.
Please run yarn global add @vue/cli-service-global and try again.

Let’s run the following (use yarn if you prefer):

npm install -g @vue/cli-service-global

Now if we do our npm run serve command again, we should be greeted with the following:

DONE  Compiled successfully in 2279ms 

App running at:
- Local:   http://localhost:8080/
- Network: http://192.168.1.9:8080/

Note that the development build is not optimized.
To create a production build, run npm run build.

If everything went well, you should be be seeing the following in your browser:

VueJS Welcome Screen

Let’s Get a Base Layout Going

In an effort to not get too complicated to someone just diving in, as I’d prefer to use TailWind CSS, we’ll instead use the following for the purposes of this demo:

PureCSS

With this, we need to pop into our src/App.vue file and scroll to lines #19 - #28 which should look similar to the following:

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

We’re going to replace this with something simple and easy:

<style>
    @import "https://unpkg.com/[email protected]/build/pure-min.css"
</style>

To actually make use of this, let’s update our src/App.vue file which should look like this for lines #1 - #6:

<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

We’re going to update this with the following include two placeholders for nav and footer as we’ll add components in a moment:

<template>
  <div id="app">
    <div class="pure-g">
      <div class="pure-u-1">
        [nav]
      </div>

      <div class="pure-u-1">
        <img alt="Vue logo" src="./assets/logo.png">
        <HelloWorld msg="Welcome to Your Vue.js App"/>
      </div>     

      <div class="pure-u-1">
        [footer]
      </div> 
    </div>
  </div>
</template>

At it’s core, this is very simple; we took away the default #app styling, added a PureCSS row for our [nav] and [footer] sections and tested that everything outputted without any errors.

Let’s Talk Components

Components are reusable Vue instances with a name; think of them liked a share piece of code you can re-use around your website to avoid repeating yourself (like our footer or navigation).

Note: This is personal preference, and not required, but I place my global components within src/components/templates; you’re free to alter and do these in whatever works best for you.

Let’s go ahead and create the following two files inside of our code base:

  • src/components/templates/navigation.vue
  • src/components/templates/footer.vue

Inside of our navigation.vue file, add the following as sample code:

<template>
    <div>
        [navigation_component]
    </div>
</template>
<script>
export default {
    data() {
        return {}
    },
}
</script>

In similar fashion, let’s add the following to our footer.vue file:

<template>
    <div>
        [footer_component]
    </div>
</template>
<script>
export default {
    data() {
        return {}
    },
}
</script>

With these created, absolutely nothing has changed in our application - we have to tell it that these exist and then update the code to actually output within our view. To do that, let’s open up our src/App.vue file once again. In your current file, within the script tag, you should see the following line (which we’ll leave for the time being):

import HelloWorld from './components/HelloWorld.vue'

Right below these, let’s add two lines so that it looks like the following:

import HelloWorld from './components/HelloWorld.vue'
import Footer from './components/templates/footer'
import Navigation from './components/templates/navigation'

Go ahead, save, and open up or refresh the site in your browser- uh oh, we’ve got an error:

'Footer' is defined but never used
'Navigation' is defined but never used

Don’t let this scare you, it’s a common mistake at first; it’s just ESLint yelling at you for declaring a variable (Footer and Navigation), but never actually using them within your view. For more information on this specific error, take a look at this link on ESLint.

To fix this issue though, we’re going to replace two sets of text within our src/App.vue file:

  1. [nav] should be replaced with <Navigation />
  2. [footer] should be replaced with <Footer />

Then we have one final piece of the puzzle to update which is the following code:

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}

We need to update this to include our two new components like the following:

export default {
  name: 'App',
  components: {
    HelloWorld,
    Navigation,
    Footer
  }
}

When you refresh now, you should see the following within your header and footer: [navigation_component] and [footer_component]

Woohoo, what’s next? Routes!

Now, before we actually create any navigation/menu within our simple little layout, let’s actually create a couple routes for three demo pages:

  • /about
  • /team
  • /contact

To do this, let’s add a file: src/routes.js which for now, we’ll leave empty and update in a moment.

What we need to do first is to create four single page templates/views at the following locations:

  • src/components/Home.vue
  • src/components/About.vue
  • src/components/Team.vue
  • src/components/Contact.vue

Inside of these files, let’s just add the following replacing [page_name] with Home, About, Team, and Contact:

<template>
    <div>
        <br />
        [page_name]
        <br /><br /><br />
    </div> 
</template>
<script>
export default {
    data () {
        return {}
    },
}
</script>

Let’s hop back into src/routes.js again and update it with the following:

import Home from './components/Home.vue';
import About from './components/About.vue';
import Contact from './components/Contact.vue';
import Team from './components/Team.vue';

const routes = [
    { path: '/', component: Home },
    { path: '/about', component: About  },
    { path: '/contact', component: Contact  },
    { path: '/team', component: Team  },
];

export default routes;

Last, but not least, to get this running we need to make three small changes to our src/main.js file:

import VueRouter from 'vue-router'
import routes from './routes'; // NEW ADDITION #1
Vue.use(VueRouter);
const router = new VueRouter({mode: 'history', routes}); // NEW ADDITION #2
new Vue({
  router, // NEW ADDITION #3
  render: h => h(App)
}).$mount('#app');

But wait, you want to actually see your content within the display? Silly me. :) To do that, let’s hope into our src/App.vue file and swap two lines:

Current:

<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>

New:

<router-view />

We need to actually remove the HelloWorld component now, otherwise we’ll have that ESLint error again:

Current:

import HelloWorld from './components/HelloWorld.vue'
import Footer from './components/templates/footer'
import Navigation from './components/templates/navigation'

export default {
  name: 'App',
  components: {
    HelloWorld,
    Navigation,
    Footer
  }
}

New:

import Footer from './components/templates/footer'
import Navigation from './components/templates/navigation'

export default {
  name: 'App',
  components: {
    Navigation,
    Footer
  }
}

If everything is working correctly, you should see the following outputted within your localhost:

[navigation_component]
[home]
[footer_component]

In order to showcase some example links and make it so you can actually traverse your new site, let’s hop into our src/components/templates/navigation.vue file and update with the following between the <template> tags:

<div class="pure-menu pure-menu-horizontal">
    <router-link to="/" class="pure-menu-heading pure-menu-link">Lesson #1</router-link>
    <ul class="pure-menu-list">
        <li class="pure-menu-item">
            <router-link to="/" class="pure-menu-link">Home</router-link>
        </li>

        <li class="pure-menu-item">
            <router-link to="/team" class="pure-menu-link">Team</router-link>
        </li>

        <li class="pure-menu-item">
            <router-link to="/about" class="pure-menu-link">About</router-link>
        </li>

        <li class="pure-menu-item">
            <router-link to="/contact" class="pure-menu-link">Contact</router-link>
        </li>                                    
    </ul>
</div>

What is the bloody router-link and why is it in our code? By using a router-link, you don’t loose the state of the page as nothing is ever actually refreshed like if an href was used - thus the smooth page loads as you traverse around the site. For some more information on this, please take a look at the following:

Final Cleanup

In order to close this out, let’s make one final change and update with the below (between <template> tags), just to showcase our other unused component; src/components/templates/footer.vue

<div>
    © 2020
</div>

Close Out

There you have it, a super simple Vue JS application running on your local machine; now I realize, this isn’t advanced, it’s not fancy, but this is the basics I wanted to lay out as the ground work before jumping into some more fun stuff over the next couple posts to include integrating with 3rd party API’s, data storage with NodeJS, working on authentication, etc.

Have you built something cool with VueJS? Do you have questions or did I leave a mistake in the above? Say howdy!

:: Link to GitHub Repository: vuejs-lesson-1

  1. With the JavaScript community especially, I know and understand there are some serious loyalties to certain frameworks; this post is not saying that Vue JS is the best, it’s just what I’ve been playing with lately and wanted to share some information/knowledge.