|

Vuejs Router Tutorial

Vuejs Router

We’ve been covering a whole lot of information about the Vuejs JavaScript framework. In this tutorial we’ll take a look at the Vue Router, which allows developers to create SPA’s, or so called Single Page Applications. The Router is the important feature of a single page application, since without it we couldn’t create one. In a single page application, there is only one page. It could be just an index.html file for example, which hosts a Vuejs application. This single page is then used to simulate navigation to the user. The URL’s do change in the browser window, however, Vuejs is actually just re-rendering this single index.html page as the URL changes. This gives the effect to the user of visiting different html pages, but in reality, it’s always the same page which is getting re-rendered. With this approach, we are no longer loading a new page on each http request to the server and then attaching Vuejs to certain parts of the page. Instead, the entire application is handled through Vuejs. To accomplish this approach, we need to learn about the main building block of a single page application in Vue, and that is the Vuejs Router.


Setup Vue Router

We recently talked a little bit about dynamic components in Vue, and this topic is related to our study of the Vue router. In other words, with routing we will be switching out different components in the application to achieve the desired effect. You can almost think of each component as an individual web page. Before we get there however, we need to actually set up the router in our Vue project. First, off let’s install Vue Router as it is not included by default with Vue itself. Go ahead and type the following at the command line.

npm install --save vue-router

Once this completes, if you inspect package.json, you will see a new dependency for the router like so:


package.json

Excellent! You have now successfully installed the Vue router into your project.


Add The Router and Configure Some Routes

Now that we have the router installed, we can actually add it to the application and set up some routes. So first off, you can open up the main.js file. Here we will do two things. We will import the router, and we will specify to use the router.


main.js


Set Up routes.js File

We can place our routes in a single location for good code organization. We can create a new routes.js file now for this purpose.
routes-js file

In the routes.js file, we can export a constant which will hold our routes. This constant will hold an array, and the array is a collection of objects with each object representing a particular route. Pretend you are beginning a website, and you have two pages. When you visit one URL, a particular page will load. When visit a different URL, a different page will load. Here, we will translate that idea into Vuejs code.


routes.js

PageOne and PageTwo are Vue components that represent a page. In the example above, we are importing those components into the routes file. After that, we can see two objects in the routes array. Each object has a path and a component. The path represents what you see in the URL bar of the browser window. The component is the page (actually component) which loads when you visit that url.


Register Your Routes

In order to use our new routes, we need to register them in the main.js file. Here is what that would look like:


main.js


Designate Where To Display Pages (Components)

So far we have two different routes, and each route will display a given component when that particular URL is visited. At this point, we need to decide where those components will actually be rendered. These components will be rendered in the App.vue file using the special built in <router-view> component which ships with Vuejs.


App.vue

With all of this in place, we should now have two routes which will be working in our application. Note that we have our two components stored in the components directory like so.
two pages or components

Just so we know what will be loading, the components are super simple. We only want to see how the router works.


PageOne.vue


PageTwo.vue

Visting the given URL’s shows us that the router is now working!


http://localhost:8080/#/page-one

vue page one route


http://localhost:8080/#/page-two

vue page two route


Configuring A Default Route

We have two components representing two different pages in the application and the Vue router example is loading them quite nicely. We should also have a home page or default route so to speak. Meaning, if a user simply loads the base URL of /, then we should indeed see the home page. First, we can create a new component named Home.vue.
default route vue

Let’s go ahead and populate the Home.vue component with some simple markup.


Home.vue

We can now add the route for the home page to our routes.js file.


routes.js

Loading the home page URL will now display a nice home page.
http://localhost:8080/#/
vue default route home page

Looks pretty good! Note that the links are not actually active yet, we will see how to make a vue router link in a Vue SPA in just a bit. For now, we are just excited to have a home page, and two additional pages that we can navigate between based on the URL that we type.


Hash and History Mode

You may have noticed that a hash symbol (#) was appended to the URL in the section above. This is put in place automatically by the Vue Router. This is the default setup that the Vue Router makes use of. This is quite common in single page applications. The reason for this is because if there is no hash symbol present, then each time a user hits enter or clicks a link, that request is sent off to the server. This is just how internet browsers work. The problem with this in an SPA however, is that we do not actually want to send the request off to the server. We instead want to handle all of the routing to different pages in the single page application itself. This happens all on the client side, no server required. The hashtag is therefore used as a delimiter of sorts. Anything before the hashtag, is what is fetched from the server. So essentially, index.html is the only file to be served from the server. Anything after the hashtag is the route to use by the Vuejs router.


How To Remove The Hashtag

Maybe you want to remove that hashtag from the URL structure. If you would like to do this, you can. You simply must enable history mode like so in your main.js file.
main.js


Adding Links With <router-link>

We already set up a nice home page which has two nice buttons the user should be able to click and navigate to a particular page in the SPA. This is not set up yet, but now we will activate those links. To make a link using the Vue Router, we can use the built in component <router-link>. What we are going to do is remove the href property altogether from our anchor tags, simply wrap the text we want to make a link with the <router-link> component. For example, to link to page-one, we could use <router-link to=”/page-one”>Click for Page 1</router-link> and to link to page-two we could use <router-link to=”/page-two”>Click for Page 2</router-link>. Here is how we can add those links to the home page.


Home.vue

Now we can see that we have active links for the buttons, in addition to the history mode activated. There is no hashtag in the URL browser bar.
vue router link example

Pretty cool! Also note that when we click each link, the page is not reloading. This is because when you use <router-link>, there is an implicit click listener put into action. Therefore, when a user clicks, the default behavior of sending an http request to the server does not happen. Instead, Vue Router listens to the click event and loads the correct route as needed.


Styling Active Links

Let’s now extract our links to a dedicated navigation area and configure styling for active links. This is a super common design and we want to know how to do it. So first up, let’s add a new component to the project called Navigation.vue. In this file, we can add the following markup.


Navigation.vue

Of course we also need to import this file into our App.vue instance and register it.


App.vue

Check out the active link styling.
vue router active links styling

There are a few things to discuss regarding the styling of active links here. Generally, we will be swapping out any anchor tags entirely with the router-link tags. This is because when you use <router-link> at actually renders to an <a> in the browser. Instead of using an href attribute, we use the to attribute. Just as we can apply a class to an anchor tag to give it a nice look, so too can we apply a class to the <router-link> tag. So as you can see, we did apply .nav-link and we get the desired effect. One thing that does occur when using <router-link> is that you lose the typical pointer you would see for a cursor. To overcome this, we simply apply some inline styling of style="cursor: pointer" to mitigate that. For styling the active link, all you have to do is apply the active-class attribute to <router-link>. Vue will intelligently figure out which link is active, and if it is, the given class will be applied. You may also notice that we use the exact attribute on the home link. This is to make sure that the active class is only applied to the home page when the home page is active. Otherwise, the home link will appear active even when clicking over to page one or page two.


Using Vue Router Push

In addition to navigating with <router-link>, we can also navigate in a programmatic fashion with the push() method of the router object. To demonstrate this, we can add a new button on Page Two that when clicked will trigger a method in our code which will perform a navigation for us. Let’s change the markup of the PageTwo.vue component to the following.


PageTwo.vue

We can see what is happening in the code above. In our component, we added a click listener to the <button> element. Therefore, when a user clicks that button, the pushHome() method is called. In the pushHome() method we are accessing the Vue instance and then the router instance as we see prefixed with the dollar sign. This is kind of the typical way to access a 3rd party plugin. The dollar sign tells us that $router is an object being provided from another package. Off of the $router, we can then make that call to push(). This method allows us to push a route onto the stack of existing routes. This ensures the back and forward buttons of the browser will continue to work fine. Also note that we simply passed a string representation of the route we want to navigate to. You can also pass an object such as {path: ‘/’} if you like. With that we now know how to navigate in our Vue application by using <router-Link to=”/”> and by using the router push method for example this.$router.push(‘/’). Here it is in action.
vue router push example


Vue Router Params

We know how to set up static routes which do not have any data associated with them. What about including dynamic parameters such as passing a unique id with a route? We can do this with router params. We will explore that now. Let’s revisit our routes.js file and examine a new addition.


routes.js

Notice the :id as part of the route for page-one. What this means is that we can pass a piece of data to that route, and retrieve it using id. With that in place, let’s modify the Navigation.vue markup just a bit.


Navigation.vue

Now we are hard coding the value of 17 in the id portion of the target route. Clicking on that particular route now shows up in the browser URL bar with the hard coded id which we specified.
vuejs router params


Retrieving Dynamic Parameters

In order to fetch a dynamic parameter from a route, you can use this.$route.params.id in the data() method of the component. Let’s see how we can display the id in the UI of page-one when visiting that page.


PageOne.vue

Now when you visit the page-one route, the id is in fact displayed on the page.
fetching dynamic params vue router


Nested Routes

Now we will see how to add some nested routes to our application. Let’s consider we have two sub pages associated with PageTwo.vue. When the user navigates to PageTwo.vue, we want them to be able to then be presented with a new sub menu of choices which allows them to visit sub pages of PageTwo.vue. To accomplish this, we can use nested routes, or sub routes within the PageTwo.vue component. We will start by modifying the routes.js file where we can add children routes.


routes.js

In the above snippet, we see three new components PageTwoMenu, TwoA, and TwoB, are being imported. We can also see that the route for /page-two now has a new children array. This array holds sub routes, or nested routes, of the PageTwo.vue component. Note that when we define the path of these sub routes, we omit the /, and this tells Vue to append the route to /page-two automatically. The route with an empty string will load the PageTwoMenu.vue component. The other two defined nested routes will create a route of /page-two/a and /page-two/b loading the TwoA and TwoB components respectively. Let’s look at the sub menu we are creating in PageTwoMenu.vue.


PageTwoMenu.vue

PageTwo.vue now needs a new <router-view> instance to display these nested routes.


PageTwo.vue

Check it out!
vuejs nested routes example


Named Routes

Vue router offers the ability to create named routes. Let’s modify the routes.js file to add named routes to a couple of routes to see how they work.


routes.js

We have now applied a named route to both the / and /page-one routes. This means that in our application, we can now simply refer to those routes by name. The first is ‘home’ and the next is ‘one’. To target those routes from a <router-link> or push() method we can update our code like so.


Navigation.vue

If you would like to pass an object containing the named route to the to attribute, it must now be prepended with a colon. If you were using the push() method, you could simply do something like this.$router.push({name: 'home'});


Query Parameters

To set a query parameter in the route, you can simply add it to the to attribute of a <router-link> Let’s see that here.


PageTwoMenu.vue

Now we want to retrieve any information stored in that query parameter. We can do that with $route.query.xyz like we see here.


PageTwo.vue

vue router query params

You may also use object syntax like we see here.


Navigation.vue


Home.vue

vue router query params example two


Configure A Redirect

Just like any other web application, you may need to redirect the user at some point. If you need to redirect a user, it is quite easy to do. As a quick example, we can set up a vue router redirect to a specific page in addition to a catch all redirect so that if a user types gibberish into the browser you could just send them to the home page for example.


routes.js


Router Transition Animation

A pretty neat thing you can do with rouets in Vuejs is to apply transitions. In other words, we can animate the switching from one route to another route in our application. To do this, we will wrap the component with a component. What we can do is assign a name to the transition, and then provide the css rules to provide that effect.


App.vue

routerview transition animation


Vuejs Router Tutorial Summary

In this tutorial we had a great introductory look at routing in the Vue js framework. We learned how to install the package into our application, and begin setting up routes right away. In addition to this we covered navigation, passing parameters, working with query params, loading components, setting up redirects, and much much more. To be fair, there is even more to learn and you’ll need to visit the docs to continue with your routing journey! The key takeaway, is that if you want to go beyond using Vue on individual web pages served from the server, then you need to dive into the Vue Router so you can build your own SPA or Single Page Application.

|