Monday, 15 May, 2017 UTC


Summary

Part1 of this tutorial dealt with the basics of building a single page application, with page linking automatically done by Vue. In this tutorial, you will learn how to:
  • pass parameters alongside the routes, and
  • use route guards to protect routes and block off non-authenticated users from visiting the site.
Starting off from the end of the last tutorial, head over to the GitHub repository to clone and continue with the application.
What will you build?
You are going to build on the existing project done in Part 1, add navigation guards and a route to pass parameters.
Here is a pictorial view of what we will be building.
Passing parameters to routes
In Vue, parameters can be passed to a route by simply putting the : attribute before the parameter name. This is somewhat similar to the routing mechanism in Laravel. If you are familiar with Laravel, the {} annotation is used to specify a route.
Look at the example below, taken from the Vue router documentation.
{ path: '/user/:id', component: User } 
From the example, it can be said that the route will give the result of /users/2 , or any integer in place of 2. Whatever content the parameter holds will be referred to as the “id”, which can be accessed using $route.params.id in the User component, which was declared as its component. Let’s begin!

Creating the parameter route

Create a new component in the src\components folder called Param.vue , and copy the following contents into it:
//src\components\Param.vue
export default {
    name: 'Param',
    data () {
        return {
        UserInput :''
        }

    }, 
    methods:{
        GoToRoute : function(){
        this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }})
        }
    }
}
In the above piece of code, a param component was defined, which is the template that holds a text box and a button.
Now, go to the main.js file, import the Param component, as well as create a path that handles the route.
Just above the Const routes block of code, add the following import:
//main.js
import Param from './components/Param 
After doing the above and importing the param component, replace the routes block with this:
//main.js
//define your routes
const routes = [
//route for the home route of the webpage
{ path: '/', component: Hello },
//route for the about route of the webpage
{ path: '/about', component: About }, 
//route for the param route of the webpage
{ path: '/param', component: Param }
]
Notice that in the above piece of code, the only difference that occurred was the addition of the param route. However, there is one more step to go so that the route can be shown with the about and home links.
Use the router link tag in our App.vue file, and add the following line of code, just after the “about” link:
<!--src\components\App.vue-->
<router-link v-bind:to="'/param'">Param Link</router-link>
Take a look at the homepage, it should look like this:
Notice that the param link is just after the “about” link. Click on the param link, and you should see the following:
Open up the developer's tool in the console. If you click on the button, you will likely encounter this error.
  [vue-router] Route with name 'Paramdetails' does not exist
This is because, in the code above, the method attached to the button triggers this:
this.$router.push({ name: 'Paramdetails', params: { id: this.UserInput }}), which has not defined any route called paramdetails that accepts parameters.
The next step is to create the component that handles the route. Create a new file in src/components called paramedetails.vue, and paste the following contents into it.
<!--src/components/paramdetails.vue-->
    The paremeter value that was passed to me is: {{ $route.params.id }}

    export default {
    name: 'paramdetails'
    }
This creates a component that holds a span element, which also prints out the parameter that was passed to it. For this to work, add this new component to the routes.
Just above the Const routes block of code, add the following import:
//main.js
//import paramdetails component
import paramdetails from './components/paramdetails'
After doing the above, and importing the paramdetails component, replace the routes block with this:
 //main.js
   //define your routes
    const routes = [
    //route for the home route of the web page
    { path: '/', component: Hello },
    //route for the about route of the web page
    { path: '/about', component: About }, 
    //route for the param route of the web page
    { path: '/param', component: Param },
    //route for the paramdetails passing in params
    { path: '/Paramdetails/:id', component: paramdetails, name: 'Paramdetails' }
    ]
Notice that the last route has two new adjustments, which was not visible in other routes. The first adjustment is the : id, which is the placeholder for the routes you are passing in. The second adjustment is the name object in the route object.
To understand the name property in the object, know that just like any other router, the Vue router contains the concept of naming routes. Instead of remembering the full URL of the new route, the shorter way of calling routes is by naming the routes. Also, take a look back at the GoToRoute method in the param component, you will see that the router object is being pushed, which identifies the route by name.
Now, click on the param link link, and type in 52 in the text box, for example. Then click the go to route button, and you should see a page like this:
That is it! You have just passed in your first route to the component. Super easy, isn't it?
Using route guards
A route guard is a watcher that watches for changes in the routes and performs some actions, either before the route is transitioned into the next one, or after the route has been transitioned. Route guards can be used to protect routes against non-authenticated users from visiting the site. Vue router has global guards, per-route guards, as well as component guards.
There are two major global routes produced by Vue router namely: beforeEach and afterEach guards. As the name implies, the “beforeEach” is performed before a new route is transitioned, as opposed to the “afterEach” guard.
Per-routes guards can be added to the route object of the particular route to be guarded as a callback, while the “in-component” guards are defined in the components that handle those routes. For the purpose of this tutorial, stick to the “beforeEach” global route.
Open the main.js file, and immediately after the routes constant, add the following:
//main.js
//place the router guard
router.beforeEach((to, from, next) => {
    //check if the path user is going to is our param path
    if(to.path == '/param'){
        //check if the user item is already set
        if(localStorage.getItem('user')==undefined){
            //prompt for username
            var user = prompt('please enter your username');
            //prompt for password
            var pass = prompt('please enter your password');
            //check if th username and password given equals our preset details
            if (user == 'username' && pass == 'password'){
            //set the user item
            localStorage.setItem('user', user);
            //move to the route
            next();
            }else{
            //alert the username and pass is wrong
            alert('Wrong username and password, you do not have permission to access that route');
            //return, do not move to the route
            return;
            }

        }

    }

    next()
})
The “router.beforeEach” function was called and it takes three arguments that are passed to it by the Vue router. The to parameter refers to the object of the path to be accessed, while the from parameter refers to the object of the previous path.
Check if the “to.path” is /param, which is the path for the route to be protected. If the path corresponds to the one to be protected, check the “localStorage” data holding the user details to see if it is defined. If the “localStorage” data is not defined, prompt for the username and password, and create the “localStorage” data. If it is defined, the function continues and the route is visible to the user.
Note: The next function must be called so that the router can process the user to the next page. If the function isn't called, a blank screen could come up. In this tutorial, a raw string of username and password was used for the authentication details. However, a lot more can be done, such as requesting user authentication via a server.
Conclusion
You should now be able to pass parameters to routes, know what named routes are, and how to create them. Also, the types of route guards, as well as an implementation for the “beforeEach” route guard was explained.
Now, you should be able to create a single page application, register routes, pass in parameters to the routes, as well as guarding the routes. On these premises, you can begin to build awesome single page applications.