# Routing

Vue applications are mostly Single Page Applications (SPA). The server always serves a single HTML page, and navigation between the application pages/sections is managed on the client side in JavaScript. This approach allows smoother transitions between pages, and reduces the number of server calls needed to navigate between pages. This is essential for Progressive Web Apps or web applications that want to have offline features.

The routing of a SPA is therefore managed on the client side, and the Vue team provides a library for this purpose: vue-router. This router allows you to associate routes (URLs) with Vue components, and offers many features:

  • Routes tree configuration
  • Modular configuration based on components
  • Dynamic parameters handling: path, query, wildcards...
  • Integration with Vue transitions system
  • Two modes:
    • by hash (mywebsite.com/#/page1)
    • by history (browser history is handled in JS with auto-fallback for IE)

# Installation

If you did not install it during initial project configuration, you can now install vue-router now with npm.

Create a src/router directory and a router/index.js file to hold router configuration. The main.js file will have to be modified to declare this new router in the application:

npm install vue-router




 


import router from "./router";

createApp(App)
  .use(pinia)
	.use(router)
	.mount("#app")

# Router Configuration

The router is created by taking a list of routes as parameters. Each route associates a URL pattern with a certain component. When the page loads, or when the URL changes, the router will resolve which route is associated with this new URL.

/** src/router/index.js **/
import { createRouter, createWebHistory } from 'vue-router'
import HelloWorld from "@/components/HelloWorld.vue";

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: "/hello/:name",
      name: "hello",
      component: HelloWorld
    }
  ]
})

export default router;

Once the route resolution is complete, a component has been associated with the current URL. This component is then injected in place of the <router-view /> element. This element is usually placed in the root component App.vue. The elements around <router-view /> form the layout structuring your application: a header, a navigation bar, a footer etc.

<template>
  <div class="app">
    <header><h1>My website</h1></header>
    <router-view />
    <footer>Made with Vue</footer>
  </div>
</template>

Vue-router includes a globally declared <router-link> component, which can substitute <a> tags for any internal navigation done via this router.

The advantage of this component over traditional <a> tags is that the links will always match your configuration (hash or history) and can be static or dynamically generated by route names and parameter lists:

<router-link to="/home">Homepage</router-link>
<router-link :to="{ name: 'hello', params: { name: 'John' } }">
  Dynamic link
</router-link>

The router has methods to programmatically navigate between pages:

router.go(-1); // go to previous page

let nextId = router.currentRoute.params.id + 1; // get URL path param
router.push(`/article/${nextId}`); // navigate to a new page by URL

Thanks to the router plugin, you can easily get a reference to the router from all your components:

// in component options
this.$router // points to router instance
this.$route // points to router.currentRoute

# Practical Work: Implementing the router

  1. If not already done, install vue-router as instructed ahead. Add the <router-view> element in App.vue then create the src/router/index.js file to start configuring the routes.

  2. Add a /login route linked to theLoginForm view and a /search route linked to SearchFilm.

TIP

By convention, we call the components linked to routes views, and we usually place them in the folder src/views rather thansrc/components.

  1. Add to route configuration some redirections /search route for default route (/) and all other unrecognized routes (/:pathMatch(.*)*) :
{
  path: "/",
  redirect: "/search",
},
{ 
  path: '/:pathMatch(.*)*', 
  redirect: "/search"
}
  1. Using vue-router (opens new window) documentation, replace the switch between LoginForm andSearchFilm currently based on a v-if by a navigation from one route to another with <router-view>.

  2. Navigate programatically to /search route after the login action, and to /login route after logout. Check that the transitions between these pages and the URL changes are working correctly.

  3. Bonus: Using vue-router Navigation Guards (opens new window) de vue-router, redirect the user who wants to access the film search page to /login if he is not authenticated.