The navigation guards provided by vue-router
are mainly used to guard the navigation by allowing or canceling it. Simply put, navigation guards are some hook functions during the routing process. Routing is a big process, with various smaller processes such as before, during, and after navigation, and there are hook functions in each process. These hook functions allow us to perform some operations during these processes, and that's what navigation guards are all about.
vue-router
provides a set of hooks to trigger functions at different stages of routing. Navigation guards are divided into three main blocks: global guards, route-specific guards, and component guards. As the name suggests, global guards are triggered for all routes entering navigation and are divided into three stages: beforeEach
, beforeResolve
, and afterEach
. Route-specific guards, as the name suggests, are only used in route definitions and route component objects, and have only one stage, beforeEnter
. Component guards are triggered in the route content within the component, and they have three stages: beforeRouteEnter
, beforeRouteUpdate
, and beforeRouteLeave
. Changes in parameters or queries do not trigger entering or leaving navigation guards. These changes can be handled by observing the $route
object or using the component guard beforeRouteUpdate
.
Navigation guards typically accept three parameters, but not all hook functions do so. Hook functions that do not accept relevant parameters will be specially noted.
to: Route
: The target route object to be entered, i.e., this.$route
in the component.from: Route
: The current route object about to leave navigation.next: Function
: This method must be called to resolve
the hook. It is important to ensure that the next
function is strictly called once in any given navigation guard. It can be called more than once, but only when all logical paths do not overlap. Otherwise, the hook will never be resolved or may report an error. The effect of executing this function depends on the arguments passed to the next
method.
next()
: Proceed to the next hook in the pipeline. If all hooks have been executed, the navigation state will be confirmed as confirmed
.next(false)
: Interrupt the current navigation. If the browser's URL changes, such as by user manual action or using the browser's back button, the URL will reset to the address corresponding to the from
route.next("/")
or next({ path: "/" })
: Redirect to a different address. The current navigation is interrupted, and then a new navigation is performed. Any location object can be passed to next
, and options such as replace: true
or name: "home"
can be set, as well as any options used in to prop
in router-link
or router.push
.next((vm) => {})
: beforeRouteEnter
is the only guard that supports passing a callback to next
. The callback receives the current component's vm
as a parameter. For beforeRouteUpdate
and beforeRouteLeave
, this
is already available, so passing a callback is unnecessary and not supported.next(error) (2.4.0+)
: If the argument passed to next
is an Error
instance, the navigation will be terminated, and the error will be passed to the callback registered with router.onError()
.Global guards are used to monitor all routes and are typically built directly when defining routes.
The global before guards are triggered when the route is just starting navigation and has not yet entered the corresponding component of the route. In simple terms, it is triggered earliest, but without any component or other loads at the time of triggering. This makes it ideal for implementing login-related logic. When a navigation is triggered, the global before guards are called in the order of creation. The guards are asynchronously resolved and executed, and the navigation remains in a waiting state until all guards are resolved.
Starting from 2.5.0+
, you can use router.beforeResolve
to register a global guard similar to router.beforeEach
. The difference is that the resolve guard is called only after the navigation has been confirmed, and also after all in-component guards and asynchronous route components have been resolved.
Register global after hooks. Unlike guards, these hooks do not accept the next
function and do not change the navigation itself.
Route-specific guards only have the beforeEnter
stage, which is triggered when the current component's route is entered.
You can directly define navigation guards inside the route component.
Triggered before entering the component, called before rendering the corresponding route of the component is confirmed
, at this point, you cannot access the component instance this
because the component instance has not been created before the guard is executed. However, you can access the component instance by passing a callback to next
, which will be called when the navigation is confirmed, and pass the component instance as a parameter to the callback method, as mentioned in the previous parameter next((vm)=>{})
.
The component update guard is used in dynamic routes. In dynamic routes, when switching routes, the same component is not re-rendered due to binding the same component. In order to re-render the content of the component, there are two methods. The first method is to use watch
, which requires using the props
syntax, and the other method is to define it in beforeRouteUpdate
, which will listen for changes in dynamic routes. Therefore, you can obtain the data corresponding to the asynchronous dynamic route in this hook. For example, for a path with dynamic parameters like /example/:id
, when switching between /example/1
and /example/2
, because the same Example
component will be rendered, the component instance will be reused, and this hook will be called in this situation. In this hook function, you can access the component instance this
.
Called when navigating away from the corresponding route of the component, you can access the component instance this
. This leave guard is usually used to prevent users from leaving suddenly before saving the modifications. The navigation can be canceled by next(false)
.
beforeRouteLeave
guard in the deactivated component.beforeEach
guard.beforeRouteUpdate
guard in the reused component 2.2+
.beforeEnter
in route configuration.beforeRouteEnter
in the activated component.beforeResolve
guard 2.5+
.afterEach
hook.beforeCreate
, created
, beforeMount
, mounted
.DOM
update.next
in the beforeRouteEnter
guard, and the created component instance will be passed as an argument to the callback function.