导航守卫
导航守卫
简介
在Vue中,导航守卫可以在路由切换前、切换后或者导航被触发时执行一些逻辑。
可以使用守卫来控制路由跳转、进行身份验证、进行页面权限控制等。
导航守卫钩子函数
导航守卫主要是以钩子函数实现在路由的不同时刻实现触发执行。
导航守卫主要包括以下几个钩子函数:
-
全局前置守卫 (
beforeEach
):在每个路由切换前执行。 -
全局解析守卫 (
beforeResolve
):在路由被解析时执行,在全局前置守卫后执行。 -
全局后置钩子 (
afterEach
):在每个路由切换后执行。
全局前置守卫
beforeEach
方法可以注册一个全局前置守卫,当守卫被注册后,在每次路由之前,都会执行该钩子函数。
接收参数:
to
: 即将要进入的目标路由。from
: 当前导航正要离开的路由。
返回值:
false
: 当全局前置守卫返回false
时,会取消当前的导航,不会继续进行路由跳转。路由地址
: 通过一个路由地址跳转到一个不同的地址,当前的导航被中断,然后进行一个新的导航。
全局解析守卫
beforeResolve
注册一个全局解析守卫。
和 beforeEach
类似,它在每次导航时都会触发,不同的是,解析守卫会在导航被确认之前、所有组件内守卫和异步路由组件被解析之后调用。
beforeResolve
是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
接收参数:
to
: 即将要进入的目标路由。from
: 当前导航正要离开的路由。
返回值:
false
: 当全局前置守卫返回false
时,会取消当前的导航,不会继续进行路由跳转。路由地址
: 通过一个路由地址跳转到一个不同的地址,当前的导航被中断,然后进行一个新的导航。
全局后置钩子
aterEach
注册全局后置钩子,会在路由结速后执行,和守卫不同的是,全局后置钩子不会改变导航本身。
全局后置钩子对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
全局后置勾子的参数与全局守卫相同,但没有返回值。
示例代码
- 首先在
views
文件夹中创建Home
、About
、News
三个组件文件。 - 然后在
router
文件夹中创建index.js 文件
做为路由管理文件。 -
在
index.js
文件中添加路由配置及全局守卫钩子函数。// 导入路由创建函数 import { createRouter, createWebHistory } from 'vue-router'; // 导入 视图组件 import Home from "../views/home.vue" import About from "../views/about.vue" import News from "../views/news.vue" // 创建路由表 const routes = [ { path: "/", component: Home }, { path: "/home", component: Home, name: "Home" }, { path: "/about", component: About, name: "About" }, { path: "/news", component: News, name: "News" } ] // 创建路由对象 const router = createRouter({ history: createWebHistory(), routes }); // 添加路由守卫 // 添加全局前置守卫 router.beforeEach((to, from)=>{ console.log("beforeEach -- from:", from, "to:", to) // return false // return {path: "/"} // if(to.name != "Home") // return {name:"Home"} }) // 添加全局解析守卫 router.beforeResolve((to, from)=>{ console.log("beforeResolve -- from:", from, "to:", to) // return false // if (to.name != "News") // return "/news" }) // 添加全局后置钩子 router.afterEach((to, from)=>{ console.log("afterEach -- from:", from, "to:", to) return "/home" }) export default router;
-
在
main.js
中将路由对象注册import router from "./router/index" app.use(router)
-
在组件中使用路由切换页面。
<template> <!-- 路由入口 --> <router-link class="box" to="/"> Home </router-link> <router-link class="box" to="/home"> /Home </router-link> <router-link class="box" to="/about"> About </router-link> <router-link class="box" to="/news"> News </router-link> <!-- 路由出口 --> <router-view></router-view> </template> <style> .box{ margin: 20px; } </style>
注意
vue-router
版本3和版本4在参数上有些许差别,当前教程代码使用的是版本4,关于版本3的使用方式,可自行查看官方文档了解区别。
其它导航守卫
除了全局导航守卫,VueRouter 中还提供了路由独享的守卫和组件内的守卫,此部分内容在教程中做为了解内容。
路由独享的守卫
beforeEnter
:直接在单个路由配置中添加beforeEnter
守卫。
beforeEnter
守卫 只在进入路由时触发,不会在 params
、query
或 hash
改变时触发。
例如,从 /users/2
进入到 /users/3
或者从 /users/2#info
进入到 /users/2#projects
。
它们只有在从一个不同的 路由导航时,才会被触发。
路由独享的守卫可以用于单个路由的身份验证和权限控制等。
const routes = [
{
path: '/users/:id',
component: UserDetails,
// 路由独享的守卫
beforeEnter: (to, from) => {
// reject the navigation
return false
},
},
]
组件内的守卫
Vue 可以在路由组件内直接定义路由导航守卫。
beforeRouteEnter
:在跳转到该路由前的组件加载之前触发。此时组件实例尚未创建,无法访问组件实例。
beforeRouteUpdate
:在路由即将更新(组件复用时)时触发,可以访问组件实例。
beforeRouteLeave
:在路由离开该组件时触发,可以访问组件实例。
const UserDetails = {
template: `...`,
beforeRouteEnter(to, from) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
},
beforeRouteUpdate(to, from) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
},
beforeRouteLeave(to, from) {
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
},
}
小结
通过使用导航守卫,你可以在路由切换前、切换后或导航被触发时执行一些逻辑,从而实现对路由导航的控制和处理。这可以帮助你进行身份验证、权限控制等操作,以及实现一些动态路由切换时的效果和逻辑。