vue 配置全局路由守卫

描述:
在使用next( )函数进行跳转时,如果没有对to这个去路进行拦截判断(to表示将要跳转的地址),处在死循环状态,就会报“Maximum call stack size exceede”的爆栈的情况。
解决办法:
1.对那些需要进行拦截路由,进行标记判断,不需要拦截的路由进行放行实施放行。
在这里插入图片描述

2.对to:跳转的那个地址进行判断(否则死循环)

router.beforeEach((to, from, next) => {
 if (to.meta.auth) {//对to路由信息进行判断
  let token = localStorage.getItem('token');
  if (token && token.length > 0) {
   next();
  } else {
   next('/login');
  }
 }else{
  next();
 }
})

<think>我们正在讨论Vue.js中的全局路由守卫,特别是用于页面跳转拦截的场景。用户希望了解全局路由守卫的基本概念和使用方法,以实现类似登录验证的拦截功能。以下根据站内引用内容进行解答: ### 一、全局路由守卫核心概念 全局路由守卫Vue Router提供的导航控制机制,允许在路由跳转的不同阶段插入自定义逻辑。根据引用[1]和[4]: 1. **拦截时机**:在路由切换**前**执行(对应`beforeEach`守卫) 2. **核心作用**:实现权限验证(如登录状态检查)、请求预处理等[^1][^2] 3. **执行范围**:作用于**所有**路由跳转(包括编程式导航和声明式导航)[^4] ### 二、全局前置守卫实现登录拦截 以下是基于引用[2][3]的标准实现流程: ```javascript // router/index.js import Vue from 'vue' import VueRouter from 'vue-router' import Login from '../views/Login.vue' Vue.use(VueRouter) const routes = [ { path: '/login', component: Login }, { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } } ] const router = new VueRouter({ routes }) // 添加全局前置守卫 router.beforeEach((to, from, next) => { // 1.检查目标路由是否需要登录 if (to.matched.some(record => record.meta.requiresAuth)) { // 2.验证登录状态(假设通过localStorage判断) const isLoggedIn = localStorage.getItem('token') !== null; if (!isLoggedIn) { // 3.未登录用户重定向到登录页 next({ path: '/login' }) } else { // 4.已登录用户放行 next() } } else { // 5.无需验证的路由直接放行 next() } }) export default router ``` #### 代码关键点解析: | 部分 | 说明 | |---------------------|----------------------------------------------------------------------| | `to.matched.some()` | 检查目标路由及其嵌套路由是否包含`meta.requiresAuth`标记[^3] | | `localStorage` | 实际项目中可替换为Vuex状态或Cookie | | `next()` | **必须调用**该方法结束守卫,否则路由跳转会阻塞 | | 白名单机制 | 通过`meta`字段标记需要拦截的路由,避免对所有路由进行验证[^2] | ### 三、路由守卫的参数解析 守卫函数接收三个核心参数: ```typescript router.beforeEach((to, from, next) => { ... }) ``` | 参数 | 类型 | 描述 | |--------|----------|--------------------------------------------------------------| | `to` | Route | 即将进入的目标路由对象(包含`path`、`params`、`meta`等属性) | | `from` | Route | 当前导航正要离开的路由 | | `next` | Function | **必须调用**的函数,决定后续行为: | | | | - `next()`: 放行 | | | | - `next(false)`: 中断当前导航 | | | | - `next('/login')`: 重定向到指定路径 | ### 四、实际应用注意事项 1. **避免死循环** 登录页(如`/login`)**不应**设置`requiresAuth`标记,否则会导致未登录用户在重定向时再次触发守卫,形成循环跳转[^3]。 2. **异步操作处理** 若守卫中包含异步请求(如token验证),需确保在回调中调用`next()`: ```javascript router.beforeEach((to, from, next) => { if (to.meta.requiresAuth) { api.checkToken().then(valid => { valid ? next() : next('/login') }) } else { next() } }) ``` 3. **多层嵌套路由拦截** 当父路由设置`requiresAuth: true`时,所有子路由默认继承该属性,无需重复标记。 ### 五、与其他守卫的配合 | 守卫类型 | 执行时机 | 典型应用场景 | |-----------------------|------------------------------|--------------------------------------| | **全局前置守卫** | 路由跳转**前** | 登录验证、权限检查(本案例)[^1] | | 全局解析守卫 | 路由组件解析**后** | 获取异步数据 | | 全局后置钩子 | 路由跳转**完成**后 | 页面访问统计 | | 路由独享守卫 | 在路由配置中单独定义 | 特定路由的权限控制[^2] | | 组件内守卫 | 在组件内部定义 | 基于组件的离开确认(如未保存表单) | §§相关问题§§ 1. Vue路由守卫中如何处理异步验证(如API验证token)? 2. 如何实现不同用户角色(如admin/user)的路由权限控制? 3. 在Vue3+Composition API中如何使用路由守卫? </think>### Vue 全局路由守卫详解 全局路由守卫Vue Router 提供的核心功能,用于在路由跳转前后执行自定义逻辑(如登录验证)。以下是关键概念和实现方法: --- #### 一、路由守卫类型与作用 根据拦截时机分为三类: 1. **全局前置守卫** `beforeEach` - **执行时机**:路由跳转**前**触发 - **核心作用**:权限校验、登录状态检查[^1] - **示例场景**:未登录用户访问受限页面时重定向到登录页 2. **全局解析守卫** `beforeResolve` - **执行时机**:导航被确认**前**,组件已解析 - **典型应用**:获取异步数据后渲染页面 3. **全局后置钩子** `afterEach` - **执行时机**:路由跳转**完成后** - **典型应用**:页面访问统计、跳转完成提示 --- #### 二、全局前置守卫实现登录拦截 以下是标准实现流程(基于 Vue Router v4): ```javascript // router/index.js import { createRouter, createWebHistory } from 'vue-router' const routes = [ { path: '/', component: Home }, { path: '/dashboard', component: Dashboard, meta: { requiresAuth: true } // 标记需要登录的路由 }, { path: '/login', component: Login } ] const router = createRouter({ history: createWebHistory(), routes }) // 核心拦截逻辑 router.beforeEach((to, from, next) => { // 1. 检查目标路由是否需要认证 if (to.meta.requiresAuth) { // 2. 验证登录状态(示例使用 localStorage) const isAuthenticated = localStorage.getItem('token') !== null // 3. 未登录则重定向到登录页 if (!isAuthenticated) { next({ path: '/login', query: { redirect: to.fullPath } }) // 携带来源路径 } else { next() // 已登录放行 } } else { next() // 无需认证的路由直接放行 } }) export default router ``` --- #### 三、关键参数解析 守卫函数接收三个参数: | **参数** | **类型** | **描述** | |----------|----------|----------| | `to` | `Route` | 即将进入的目标路由对象 | | `from` | `Route` | 当前导航正要离开的路由 | | `next` | `Function` | **必须调用**的解析函数 | `next()` 函数的行为: ```javascript next() // 放行路由跳转 next(false) // 中断当前导航 next('/login') // 重定向到指定路径 next(error) // 触发路由错误(进入错误处理) ``` --- #### 四、最佳实践与注意事项 1. **路由元信息** 使用 `meta` 字段标记需要拦截的路由: ```javascript { path: '/admin', component: AdminPanel, meta: { requiresAuth: true, roles: ['admin'] } // 多维度控制 } ``` 2. **避免死循环** 登录页**必须排除**在守卫拦截外: ```javascript // 在守卫中添加白名单 const publicPages = ['/login', '/register'] if (publicPages.includes(to.path)) return next() ``` 3. **异步操作处理** 支持在守卫中使用 `async/await`: ```javascript router.beforeEach(async (to) => { if (to.meta.requiresAuth) { const isValid = await api.checkToken() return isValid ? true : '/login' } }) ``` --- #### 五、与 Uniapp 的差异 > 引用站内提示:Uniapp 需使用特有 API `uni.addInterceptor`[^4] ```javascript // Uniapp 实现(对比 Vue Router) uni.addInterceptor('navigateTo', { invoke(args) { if (needAuth(args.url) && !isLogin()) { uni.redirectTo({ url: '/login' }) return false // 拦截跳转 } return args // 放行 } }) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值