9 Vue Router steps for beginners.

The router is one of the important topics when we build single page applications with Vue, there are a few of things that I wish to know to begin and really helped me get basic tasks with VueRouter.

I’m going to assume you’re already working with Vue and want to start to use VueRouter in your existing or new project. If you want to follow the next examples, please create a spa with Vue CLI 3.2.1 or high, pick the default option to setup babel, ESLINT and skip add VueRouter by default.

1- Install VueRouter and configure routes

Let’s get the basics out of the way. If we start to build a SPA or want to add routing into an existing app then install the vue-router is our first step.

npm install --save vue-router

Now let’s add the route into our app and configure one single route. First, we import VueRouter into our main.js and add the router into the Vue instance.

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

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

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

Our next step is to create the file routes.js in the root and exports a const array with json objects, with two properties path like yourapp.com/posts and component for the Vue component.

import HelloWorld from './components/HelloWorld'
import Posts from './components/Posts'
export const routes = [
{ path: '/', component: HelloWorld }
{ path: '/posts', component: Posts }
]

Back to our main.js and import the routes from the route.js file, create a router instance using new VueRouter passing to the routes and add it to the Vue instance.

import VueRouter from 'vue-router';
import {routes} from './route'
Vue.use(VueRouter)
Vue.config.productionTip = false

const
router = new VueRouter({ routes})

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

The last step is to define a place using <router-view> in App.vue for the components.

<template>
<div id="app">
<router-view></router-view>
</div>
</template>

Mission completed! .. but by default, the router adds/#/ in the URL.

2- Remove hashMode behavior.

By default router use hashMode, to get rid off #. Set mode property to ‘history’ on the VueRouter initialization.

const router = new VueRouter(
{ routes, mode: 'history'})

3- Navigate using router links and add style to the active link.

Every route defined in routes.js can be accessed using the to attribute in the <router-link> component.

<div>
<li>
<router-link to="/">Home </router-link>
</li>
<li>
<router-link to="/posts">Posts</router-link>
</li>
</div>

By default, the router link adds the css class “router-link-active” in “a”elements when it matches with the url.

To change the default behavior set the active-class attribute with a custom css class and also to avoid the problem with “/” add parameter exact, it will force the url have to match fully the router link.

<template>
<div>
<li>
<router-link to="/" active-class="selected" exact>Home </router-link>
</li>
<li>
<router-link to="/posts" active-class="selected" exact>Posts</router-link>
</li>


</div>
</template>

<script>
export default {
name: "Menu.vue"
}
</script>

<style scoped>
.selected {
border: 1px solid salmon;
}
</style>

4- Navigate using the $router

Sometimes we need to move between components when the user does some action but without the user click in some the router-link.

The router has the push method for moving between routes.

<template>
<el-col>
<h2>HelloWorld Component</h2>
<el-button @click="gotoPosts">Go to posts page</el-button>
</el-col>
</template>

<script>
export default {
name: "HelloWorld",
methods: {
gotoPosts() {
this.$router.push("/posts");
}
}
};
</script>

5-Setting and reading router parameters.

Read and send parameters is a common task in our and the router can help to solve with few lines of code.

Back to routes.js file and include in the router path our parameter : like :name and ? if want converts the parameter as optional.

import HelloWorld from "./components/HelloWorld";
import Posts from "./components/Posts";
export const routes = [
{ path: "/", component: HelloWorld },
{ path: "/posts/:name?", component: Posts }
];

We can read the name parameter using this.$route.params object it provides access to all url params example: http://localhost/posts/dany

data() { return {
selected: this.$route.params.name,
....
}},

6- Bind dynamic params and query strings

The router-link can accept dynamic params using v-bind in the to property.

<template>
<div class="row">
<ul>
<li v-for="article in articles" :key="article.id">
<router-link v-bind:to="'posts/' + article.id" >{{article.description}}</router-link>
</li>
</ul>
</div>
</template>

<script>
export default {
name: "Posts",
data() { return {
selected: this.$route.params.id,
articles: [ { id: 1, description: 'Lebron out '},
{ id: 2, description: 'Curry out '}
]
}}
}
</script>

The query string is a common way to pass values between pages like http://localhost:8080/posts?limit=3 The route gives to us access to query string like the params.

limit: this.$route.query.limit ? this.$route.query.limit : 2,

7- Child and named Routes

To setup nested or child inside the component posts like post/1 or posts/1/edit, add children property inside our ‘/post’ route.

{ path: '/posts', component: Posts,
children: [
{ path: ':name', component: Details},
{ path: ':name/edit', component: Edit}
]
}

Like the App.vue add another <router-view> in the posts.vue component.

<router-view>
</router-view>

And don't forget update router link with the new route.

<li v-for="article in filterArticles" :key="article.id">
<router-link :to="'/posts/' + article.description" >{{article.description}}</router-link>
<router-link :to="'/posts/' + article.description + '/edit'"> Edit </router-link>
</li>
What…+ t + f +..k.

Yes… is ugly and nasty, but calm.. we can identify our routes with names using “name”, back to route.js and add attribute name.

{ path: ':name/edit', component: Edit, name: 'edit'}

Using the name for our routes we can write cleaner and meaningful router link passing an object with props name and params.

<router-link 
:to="{name: 'posts', params: {name: article.description}}" >{{article.description}}
</router-link>
<router-link 
:to="{name: 'edit', params: {name: article.description}}">
Edit </router-link>

8- Redirect and Route Wildcards

If we want to redirect our user from someone path to another set attribute redirect with the path our named route.

{path: '/login', redirect: '/posts'}

Using * in the path attribute it catch all no don’t exist routes in our routes like http://localhost/lalsdalksdlkasdlkjads.

{ path: '*' , redirect: {name: 'posts'}}

9- Using Guards to protect routes.

To keep control of the navigation like when the user entering or leave a component or route, using the beforeRouteEnter, beforeEach and beforeRouteLeave methods.

These methods accept a function as an argument with to, from and next params.

The Next parameter is a function to abort or continue the navigation, it accepts a path as “/posts” or false to abort navigation and we can read the requested route using to params.

Our first steps create the login component and set the route, add a method for saving in localStorage the key authkey and assign to the login button.

<template>
<el-row>
<el-input></el-input>
<el-button @click="setToken">Login</el-button>
</el-row>
</template>
<script>
export default {
name: "Login",
methods:{
setToken() {
localStorage.setItem('authkey',2222);
}
}
}
</script>

Then configure the route in route.js

{ path: '/login', component: Login}

Configure as Global
Calling beforeEach in the main.js file, it will be executed for all routes defined in routes.js.

The next example is calling the beforeEach method and read if the requested path is not login, we will check if the browser has authkey in the localstorage to allow continue or be moved to the login component.

router.beforeEach((to, from, next) => {
if(to.path !== ‘/login’) {
localStorage.getItem(‘authkey’) ? next() : next(‘/login’)
}
else {
next()
}
})
new Vue({
router,
render: h => h(App),
}).$mount(‘#app’)

The setup inside the components is very similar, but using the methods beforeRouterEnter and beforeRouteLeave with the same functionality and only affect our current component.

beforeRouteEnter(to, from, next){
localStorage.getItem(‘authkey’) ? next() : next(false)
},
beforeRouteLeave(to,from,next){
localStorage.getItem(‘authkey’) ? next(false) : next()
}

That’s it!

Hopefully, that will give you a bit of a head-start on VueRouter, and help you avoid some of the more common mistakes. If you enjoyed this post, please share it.