What is vue-router?
The vue-router npm package is the official router for Vue.js. It integrates closely with Vue.js core to make building Single Page Applications with Vue.js a breeze. Features include nested routes/mappings, modular, component-based router configuration, route params, query, wildcards, transitions, fine-grained navigation control, and view transition effects powered by Vue.js' transition system.
What are vue-router's main functionalities?
Dynamic Route Matching
This feature allows you to create routes that are dynamically matched to the path. For example, different user IDs can be matched to the same route pattern.
{"const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User }
]
})
const User = {
template: '<div>User {{ $route.params.id }}</div>'
}"}
Nested Routes
This feature allows you to map nested paths to components. It's useful for creating sub-sections of a page without having to create complex configurations.
{"const router = new VueRouter({
routes: [
{ path: '/user/:id', component: User,
children: [
{
// UserProfile will be rendered inside User's <router-view>
path: 'profile',
component: UserProfile
}
]
}
]
})
const User = {
template: '<div>User <router-view></router-view></div>'
}"}
Programmatic Navigation
Vue-router allows you to navigate without using <router-link> by using the router instance methods.
{"router.push('/home')
router.replace('/home')
router.go(-1)"}
Named Routes
Instead of using URLs, you can navigate using route names, making your code more readable and maintainable.
{"const router = new VueRouter({
routes: [
{ name: 'user', path: '/user/:id', component: User }
]
})
// navigate to a named route
router.push({ name: 'user', params: { id: 123 }})"}
Route Guards
Route guards are used to protect routes that require authentication, perform checks before entering a route, or confirm navigation away from a route.
{"const router = new VueRouter({
routes: [
{ path: '/secret', component: Secret, beforeEnter: (to, from, next) => {
// ... guard logic
next();
}}
]
})"}
Other packages similar to vue-router
react-router
React Router is a standard library for routing in React. It has a similar set of features to vue-router, such as dynamic route matching, nested routes, and navigation control, but it is designed for React instead of Vue.
angular-router
Angular's router is a powerful navigation library for Angular. It offers features like lazy loading, nested routes, and route guards. It is comparable to vue-router but is used within the Angular ecosystem.
reach-router
Reach Router is a small, simple router for React that is accessible and easy to use. It is similar to vue-router but with a focus on simplicity and accessibility.
vue-router-next
Status: Beta
Know issues
Breaking changes compared to vue-router@3.x
-
The mode: 'history'
option has been replaced with a more flexible one named history
:
import { createRouter, createWebHistory } from 'vue-router'
createRouter({
history: createWebHistory(),
routes: [],
})
-
base
option is now passed as the first argument to createWebHistory
(and other histories)
-
Catch all routes (/*
) must now be defined using a parameter with a custom regex: /:catchAll(.*)
-
router.match
and router.resolve
are merged together into router.resolve
with a slightly different signature. Check its typing through autocomplete or Router's resolve
method
-
router.getMatchedComponents
is now removed as they can be retrieved from router.currentRoute.value.matched
:
router.currentRoute.value.matched.flatMap(record =>
Object.values(record.components)
)
- The
append
argument has been removed. You can manually concatenate the value to an existing path
instead.
-
RouterLink
append
prop has been removed as well. Use the same workaround as above.event
prop has been removed. Use the v-slot
API instead. See RFC.tag
prop has been removed. Use the v-slot
API instead. See RFC.exact
prop has been removed. The caveat it was fixing is no longer present. See RFC.
-
If you use a transition
, you may need to wait for the router to be ready before mounting the app:
app.use(router)
router.isReady().then(() => app.mount('#app'))
Otherwise there will be an initial transition as if you provided the appear
prop to transition
because the router displays its initial location (nothing) and then displays the first location. This happens because navigations are all asynchronous now. If you have navigation guards upon the initial navigation, you might not want to block the app render until they are resolved.
-
On SSR, you need to manually pass the appropriate history:
let history = isServer ? createMemoryHistory() : createWebHistory()
let router = createRouter({ routes, history })
router.push(req.url)
router.isReady().then(() => {
})
-
The object returned in scrollBehavior
is now similar to ScrollToOptions
: x
is renamed to left
and y
is renamed to top
. See RFC.
-
transition
and keep-alive
must now be used inside of RouterView
via the v-slot
API:
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
See more on the KeepAlive and the Transition examples. See RFC.
-
parent
is removed from Route locations (this.$route
and object returned by router.resolve
). You can still access it via the matched
array:
const parent = this.$route.matched[this.$route.matched.length - 2]
-
pathToRegexpOptions
and caseSensitive
have been replaced with sensitive
and strict
options. They can also be directly passed when creating the router with createRouter()
. Any other option has been removed as path-to-regexp
is no longer used to parse paths.
Typings
To make typings more consistent and expressive, some types have been renamed. Keep in mind these can change until stable release to ensure consistency. Some type properties might have changed as well.
vue-router@3 | vue-router@4 |
---|
RouteConfig | RouteRecordRaw |
Location | RouteLocation |
Route | RouteLocationNormalized |
Improvements
These are technically breaking changes but they fix an inconsistent behavior.
- Pushing or resolving a non existent named route throws an error instead of navigating to
/
and displaying nothing. - resolving(
router.resolve
) or pushing (router.push
) a location with missing params no longer warns and produces an invalid URL (/
), but explicitly throws an Error instead. - Empty children
path
does not append a trailing slash (/
) anymore to make it consistent across all routes:
- By default no route has a trailing slash but also works with a trailing slash
- Adding
strict: true
to a route record or to the router options (alongside routes
) will disallow an optional trailing slash - Combining
strict: true
with a trailing slash in your routes allows you to enforce a trailing slash in your routes. In the case of nested routes, make sure to add the trailing slash to the parent and not the empty child:
let routes = [
{
path: '/parent/',
children: [{ path: '' }, { path: 'child1/' }, { path: 'child2/' }],
},
]
- To redirect the user to trailing slash routes (or the opposite), you can setup a
beforeEach
navigation guard that ensures the presence of a trailing slash:
router.beforeEach((to, from, next) => {
if (to.path.endsWith('/')) next()
else next({ path: to.path + '/', query: to.query, hash: to.hash })
})
- Because of the change above, relative children path
redirect
on an empty path are not supported anymore. Use named routes instead:
let routes = [
{
path: '/parent',
children: [
{ path: '', redirect: 'home' },
{ path: 'home' },
],
},
]
let routes = [
{
path: '/parent',
children: [
{ path: '', redirect: { name: 'home' } },
{ path: 'home', name: 'home' },
],
},
]
Note this will work if path
was /parent/
as the relative location home
to /parent/
is indeed /parent/home
but the relative location of home
to /parent
is /home
- Encoding is now more consistent. The initial navigation should yield the same results are in-app navigations.
- Values in
path
, fullPath
are not decoded anymore. They will appear as provided by the browser (most browsers provide them encoded). params
, query
and hash
are now all decoded- When using
push
, resolve
and replace
and providing a string
location or a path
property in an object, it must be encoded. params
, query
and hash
must be provided in its decoded version.
Contributing
See Contributing Guide.