# Router

Vue Router is the official router for Vue.js. It is used to add routes to SPAs, Single Page Applications.

# Add router to Vue app

# Input main.js

Add the router to the Vue Instance



 





 




import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12

# Input (router/index.js)

This is how to set up the router itself

Note the mode: 'history', on line 22 so that the URL looks "prettier".

More info on History mode






















 






import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# Input (App.vue)

To adding the links (Line 4-7) use router-link and the routing is rendered with router-view (line 9).




 
 
 
 

 



<template>
  <div id="app">
    <div id="nav">
      <router-link to="/" exact>
        Home
      </router-link>
      <router-link to="/about">About</router-link>
    </div>
    <router-view />
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11

Use the router-link for the Navigation Bar

The active link will automatically be bound to two css class="router-link-active".

# Input


 
 



<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
</template>
1
2
3
4
5
6

# In the Dom:


 
 


<div id="nav">
  <a href="/" class="router-link-active">Home</a>
  <a href="/about" class="router-link-exact-active router-link-active">About</a>
</div>
1
2
3
4

The default active class matching behavior is inclusive match. For example, <router-link to="/a"> will get this class applied as long as the current path starts with /a/ or is /a.

One consequence of this is that <router-link to="/"> will be active for every route! To force the link into "exact match mode", use the exact prop:

# Input





 
 
 



<template>
  <div id="nav">
    <a href="/" class="">
      Home
    </a>
    <a href="/about" class="router-link-exact-active router-link-active">
      About
    </a>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10

# In the Dom:



 




<div id="nav">
  <a href="/" class=""> Home </a>{' '} |
  <a href="/about" class="router-link-exact-active router-link-active">
    About
  </a>
</div>
1
2
3
4
5
6

Instead of a <a>Home</a> we can render a link as a <li>Home</li> for instance using the tag attribute.

# Input


 


 





<template>
  <div id="nav">
    <router-link to="/" tag="li">
      Home
    </router-link>
    <router-link to="/about" tag="li">
      About
    </router-link>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10

# In the Dom:


 
 


<div id="nav">
  <li href="/">Home</li>
  <li href="/about">About</li>
</div>
1
2
3
4

# Input:



 





 
 
 





<template>
  <div>
    <button @click="goHome">Home</button>
  </div>
</template>

<script>
export default {
  methods: {
    goHome: function() {
      this.$router.push({ path: '/' })
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# Output:

TIP

User $router.replace instead of $router.push to avoid adding a new entry in the history.

# Setting Up Dynamic Route Parameters

# Input: (Vue file)



 







 




 





<template>
  <div>
    <button @click="toUser">go to User</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      id: this.$route.params.id
    }
  },
  methods: {
    toUser: function() {
      this.$router.push({ path: '/user/:id', component: User })
    }
  }
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# Input: (router/index.js file)




 









 
 










import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import User from '../views/User.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  // dynamic segments start with a colon
  { path: '/user/:id', component: User }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# Nested route




 
 
 
 
 
 
 
 
 
 
 
 
 
 






const router = new VueRouter({
  routes: [
    {
      path: '/user/:id',
      component: User,
      children: [
        {
          // UserProfile will be rendered inside User's <router-view>
          // when /user/:id/profile is matched
          path: 'profile',
          component: UserProfile
        },
        {
          // UserPosts will be rendered inside User's <router-view>
          // when /user/:id/posts is matched
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 404 route

Create a component named for instance NotFoundComponent




 

const router = new VueRouter({
  mode: 'history',
  routes: [{ path: '*', component: NotFoundComponent }]
})
1
2
3
4

# Lazy Load Syntax (Code Splitting)

To make sure that not all routes are loaded right when opening the app. Using Vue's Async Components and webpack's code splitting feature

const User = () => import('./components/user/User.vue');
...
export const routes = [
    ...,
    {
        path: '/user', components: {
            default: User,
            ...
        }
    }
];
1
2
3
4
5
6
7
8
9
10
11

See the Official Vue Router doc