Vue.js Tutorial: How to Create Blog as Single Page Application with Vue.js? Part 1

In this first part of the Vue.js blog tutorial, we include Twitter Boostrap 4 into our app for nice CSS styling, connect to REST API and load all articles nicely paginated with 3rd party plugin.

SOURCE CODE

Hopely you have all necessary prerequisites installed, we can dive into our blog single page application.

If you haven’t used single file components before, in the root folder index.html file is located, which is displayed in the browser.

But all the logic, mainly components, is stored in src folder. In main.js file you can find Vue instance, which initialize whole app.

As a root component, App.vue is used, where you find all the HTML code displayed in the browser. You can clear the template, script and style tag for now, as we write our custom code throughout this tutorial.

Using Bootstrap in Vue.js

There is not only one way to use Bootstrap in Vue.js, but I simply add a link to CDN CSS file into index.html file, because I need only CSS, and I want to use use widely in whole app:

<!DOCTYPE html>
<html lang="en">
 <head>
 <meta charset="utf-8">
 <title>Vue.js Blog Tutorial</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
 </head>
 <body>
 <div id="app"></div>
 <script src="/dist/build.js"></script>
 </body>
</html>

If you want to use also JavaScript part in your app, not only CSS, there is Bootstrap implementation ready for you.

This is the first, but also the last time in tutorial we changed index.html file. Actually, this was the only piece of code written outside the src folder.

Structure of the Blog App

Before writing any JavaScript code, firstly think what components would be needed and how to structure the single page app.

In my case, I expect to work with 3 components:

  • App.vue, which is served by default, used as a basic template containing e.g. header and footer
  • Blog.vue, as the name says, would hold the paginated list of the articles
  • PostDetail.vue, used for detail of the article with comments

You can create all the components, but for now I work with App.vue only.

File Structure

Prepare App HTML template

At first, I prepare some HTML code into template to see, if Bootstrap styling works, and app is rendering in the browser correctly (App.vue):

<template>
  <div class="container">
    <div class="row">
      <div class="col-sm-12">
        <div class="jumbotron">
          <div class="container">
            <span class="display-4 h1">Vue.js Blog Tutorial #1</span>
            <p class="lead">Simple example how to connect to the server, paginate results, create single page app...</p>
          </div>
        </div>
     </div>
     <footer class="col-sm-12">
       <hr>
       <p class="text-center"><ahref="http://www.peterstehlik.com"target="_blank">Peter Stehlík</a>&copy; 2018 </p>
     </footer>
    </div>
  </div>
</template>

Install Vue.js HTTP Client

Now it’s time to move to more interesting part and to connect our app with the server, in my case to JSON Placeholder fake REST API.

To establish connection and receive data, plugin is needed. The core of Vue.js doesn’t contain this feature by default.

I use Vue resource plugin, which makes super easy to create GET, POST or other types of request. To install it, type into command line:

npm install vue-resource --save

You can check if the installation finished correctly in package.json (root folder), where in dependencies object vue-resource should be listed with the version installed.

It is still not ready to be used, while we need to say the app: “Please, use vue resource plugin, I need to create some requests”.

Open main.js file, which should look like this now:

import Vue from 'vue'
import App from './App.vue'
import VueResource from 'vue-resource'

Vue.use(VueResource);

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

Vue.use() syntax is generally used to enable 3rd party plugins in the app. You will see it in the action also in the case of other plugins which will be used in tutorial.

Loading Data From the Server Tutorial

In App.vue file, I need some variable to store all the articles => posts variable.

Then, I use created method from the lifecycle instance for receiving the list of the articles.

Finally, I loop through all articles and display titles separated with horizontal line.

App.vue:

<template>
<div class="container">
  <div class="row">
    <div class="col-sm-12">
      <div class="jumbotron">
        <div class="container">
          <span class="display-4 h1">Vue.js Blog Tutorial #1</span>
          <p class="lead">Simple example how to connect to the server, paginate results, create single page app...</p>
        </div>
      </div>
    </div>

    <section v-for="blog in posts">
      <h2>{{ blog.title }}</h2>
      <hr>
    </section>

    <footer class="col-sm-12">
      <hr>
      <p class="text-center"><ahref="http://www.peterstehlik.com"target="_blank">Peter Stehlík</a>&copy; 2018 </p>
    </footer>
  </div>
</div>
</template>

<script>
exportdefault {
  data() {
    return {
      posts: [],
    }
  },

  created() {
    this.$http.get("http://jsonplaceholder.typicode.com/posts")
      .then(response => response.json(), error => console.log(error))
      .then(json => this.posts = json, error => console.log(error));
  }
}
</script>
If everything went smoothly, you should see a long list of titles loaded from the server. This is not very user friendly, that’s why I want to add the pagination function to make nicer.

Vue.js Pagination

For the purposes of this tutorial I chose another plugin vue-paginate. It is not the only one, try to search Google for some more extensions, but this works fine, it is well documentated and you have a lot of options available.

Again, to enable using vue-paginate plugin, 2 steps are needed:

1. installation:

npm install vue-paginate --save

2. include to the app (main.js):

import Vue from 'vue'
import App from './App.vue'
import VueResource from 'vue-resource'
import VuePaginate from 'vue-paginate'

Vue.use(VueResource);
Vue.use(VuePaginate);

new Vue({
  el:'#app',
  render:h=>h(App)
})
Now, it is ready to be used. Our App.vue template changes a lot, because I want to display only 10 articles per page, then at the bottom, pagination links styled as Twitter Bootstrap pagination.
But, firstly, add variable paginate into data function:
data() {
  return {
    posts: [],
    paginate: ['blogs']
  }
},

It becomes important to provide unique key for each list to be easily identified.

And now turn endless list of articles into paginated catalogue with pagination links at the bottom (App.vue – displayed only previous “section v-for” part of the code, which is replaced by followed):

...
<div class="col-sm-12">
<paginate
  name="blogs"
  :list="posts"
  :per="10"
  tag="div"
>

<section v-for="blog in paginated('blogs')">
  <h2>{{ blog.title }}</h2>
  <hr>
</section>

</paginate>

<paginate-links
  for="blogs"
  :async="true"
  :show-step-links="true"
  :step-links="{
    next: 'Next',
    prev: 'Previous'
  }"
  :classes="{
    'ul': 'pagination',
    'ul > li': 'page-item',
    'ul > li > a': 'page-link',
  }"
>
</paginate-links>
</div>
...

See, that posts variable is used only in the list parameter of the paginate tag. Then, in the loop and for pagination links, there is blogs used, as I named the pagination.

Summary

That’s it! You have reached the end of the first part of Vue.js Blog Tutorial, where I showed you, how to make a HTTP request to the server, and paginate list of data with the help of 3rd party plugins.

Note: Next, the last part of the tutorial is going to be published on 22, March 2018.