Building a single page application with vue.js and axios.

Axios is a JavaScript plugin that allows you to make HTTP requests. We use Axios with Vue.js in this tutorial to parse a sample API. The API we used is https://jsonplaceholder.typicode.com.
We also added a pagination plugin to Vue so we can page our API requests. Learn more about axios here.

We create three components. A main component and two child components. The main component is named MainView.vue. It holds the template for the menu items and the jumbotron that describes the page that we are on.

Main View

The menu items, the page title and the jumbotron descriptions are all binded properties. We can see this in the data property.

    data () {
        return {
            msg: 'Vue and Axios',
            show: "users",
            nav: [
                {id: 1, project: 'Users', action: 'proj0', state: true},
                {id: 2, project: 'Posts', action: 'proj1', state: false},
                {id: 3, project: 'ToDos', action: 'proj1', state: false},
            ],
            page: {title: 'Users Page', footer: 'This is pulling from the users api', button: 'Refresh'},
        }
    },

In the main view we have the child components below the jumbotron.

    <div class="container" style="text-align:left;"&gt;
        <users-view v-if="show=='users'"&gt;</users-view&gt;
        <posts-view v-if="show=='posts'"&gt;</posts-view&gt;
    </div&gt;

We have a v-if property that determines when a child component is visible. We add the components using the component object.

   components : {
        'users-view' : UsersView,
        'posts-view' : PostsView,
    },

We also have to import these child components from their respective locations.

import UsersView from './UsersView.vue';
import PostsView from './PostsView.vue';

Our menus in the main component allow us to change views and switch between our child components.

     <ul class="nav nav-pills float-right"&gt;
                <li class="nav-item" v-for="link in nav" v-bind:key="link.id"&gt;
                    <a @click="navAction(link.id)" class="nav-link" v-bind:class="{ active: link.state }" href="#"&gt;
                        {{ link.project }}</a&gt;
                </li&gt;
            </ul&gt;

We render a list that when clicked on executes the navAction method. This method is shown below. It does a few things. First it decides whether a current li element is active or not.

        navAction: function (action) {
            for(var i=0; i<=this.nav.length-1; i++ ){
                if(this.nav[i].id == action){
                    this.nav[i].state = true;
                }else{
                    this.nav[i].state = false;
                }
            }
            if(action == 1 ){
                this.show = "users";
                this.page.title = "Users Page";
            }else if( action == 2){
                this.show = "posts";
                this.page.title = "Posts Page";
            }
        },

Next it changes the jumbotron details depending on where the page is at. Notice also that the show attribute is changed. This will toggle the child components views.

To manage our API requests we created an api.js file. In it we return a constant with two main functions. The getUsers function returns the users data from the api.

    getUsers(page){
        return new Promise((resolve)=>{
            axios.get('https://jsonplaceholder.typicode.com/users?_page=' + page)
            .then((response) =>{
            resolve(response.data);
            })   
        })
    },

It takes an argument named page which determines the page number we want from the api service. The other function getPosts operates the same way.

    getPosts(page){
        return new Promise((resolve)=>{
            axios.get('https://jsonplaceholder.typicode.com/posts?_page='+page)
            .then((response) =>{
            resolve(response.data);
            })   
        })
    }

In the users view component we have a created function which initially loads the data.

    created(){
         api.getUsers(1).then((data)=>{
            this.users = data;
       });
    },

In the child components we use pagination. We added a package to do this.

npm install vue-plain-pagination

Once the package is added we could use it in our child component. The element, the import statement and the component object is show below.

 <paginator v-model="currentPage" :page-count="total"&gt;</paginator&gt;

import Paginator from 'vue-plain-pagination'
 components: {
        Paginator: Paginator
 },

We can see how this looks like below. The pagination section is below the table.

The posts operates the same way. However we added pagination at the top and bottom of the page.

We manage the pages using the currentPage attribute declared in the data function.

    data() {
        return {
            posts: [],
            currentPage :1,
            total : 10,
        }
    },

We set a watch on the currentPage and update the data if the page number changes.

      watch: {
        'currentPage' : function(oldValue, newValue){
            api.getPosts(oldValue).then((data)=>{
            this.posts = data;
       });
        }
    }

This is how we update our view based on different pages from the API.

To get a better understanding of this post check out the code below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s