vue.js全局守卫写在那个文件里

admin 103 0
Vue.js全局守卫通常写在路由配置文件中,一般位于项目src/router/index.jssrc/router.js(具体路径根据项目结构调整),在该文件中,通过router实例注册全局守卫,如使用router.beforeEach()定义全局前置守卫,用于导航跳转前进行权限校验、登录状态检查等逻辑;router.afterEach()则用于全局后置钩子,适合在导航完成后执行如页面滚动、日志记录等操作,全局守卫需在路由实例创建后、Vue应用挂载前配置,以确保在路由导航过程中生效。

Vue.js全局守卫配置位置与最佳实践指南

在Vue.js项目中,全局守卫(Global Guards)作为路由控制的核心机制,承担着路由跳转前后的逻辑拦截任务,如权限校验、登录状态验证、页面标题动态修改等,初学者常面临一个关键问题:全局守卫应如何正确配置? 本文将系统解答配置位置的选择,并结合实战场景提供最佳实践方案。

全局守卫的核心配置原则:路由实例注册

Vue.js的全局守卫(beforeEachbeforeResolveafterEach)必须注册在路由实例(Router Instance)上,因此配置代码应统一写入路由配置文件,在标准Vue项目中,该文件通常位于 src/router/index.js(Vue CLI)或 src/router.js(Vite项目)。

为何必须配置在路由文件?

全局守卫的作用域覆盖整个应用,而路由实例是Vue Router的核心调度器,它管理所有路由规则,并在路由切换时触发守卫逻辑。**将守卫注册在路由实例上**,可确保所有路由跳转均经过统一拦截,避免因分散配置导致逻辑遗漏或冲突。

多场景下的路由配置定位

尽管 src/router/index.js 是通用方案,但项目创建工具(Vue CLI/Vite/Nuxt.js)可能影响文件命名,以下是典型场景:

Vue CLI项目(Vue 2/3)

默认路由配置文件 src/router/index.js 导出路由实例:

```javascript // src/router/index.js import Vue from 'vue' import VueRouter from 'vue-router' import Home from '../views/Home.vue' import Login from '../views/Login.vue'

Vue.use(VueRouter)

const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/login', name: 'Login', component: Login } ]

const router = new VueRouter({ routes })

// 全局前置守卫 router.beforeEach((to, from, next) => { const isAuthenticated = localStorage.getItem('token') if (to.meta.requiresAuth && !isAuthenticated) { next('/login') // 未登录拦截 } else { next() // 正常放行 } })

// 全局后置钩子 router.afterEach((to) => { document.title = to.meta.title || '默认标题' })

export default router


<h4>Vite项目(Vue 3 + Router 4.x)</h4>
<p>使用组合式API,路由配置位于 <code>src/router/index.js</code>,API兼容Vue Router 3.x:</p>
```javascript
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'
const routes = [
  // 路由规则同上
]
const router = createRouter({
  history: createWebHistory(),
  routes
})
// 守卫注册方式与Vue 2一致
router.beforeEach((to, from, next) => {
  // 权限校验逻辑
})
export default router

路由模块化场景

当路由规则按业务拆分(如 src/router/modules/user.js),**全局守卫仍需在合并路由实例后注册**:

```javascript // src/router/index.js import userRoutes from './modules/user' import productRoutes from './modules/product'

const routes = [ { path: '/', redirect: '/user' }, ...userRoutes, ...productRoutes ]

const router = createRouter({ history: createWebHistory(), routes })

// 全局守卫必须在此注册 router.beforeEach((to, from, next) => { // 合并后的路由才能正确拦截 })

export default router


<h3>全局守卫实战场景与代码优化</h3>
<h4>1. 动态权限控制</h4>
<p>基于用户角色(admin/user/guest)精细化控制路由访问:</p>
```javascript
router.beforeEach((to, from, next) => {
  const userRole = localStorage.getItem('role')
  // 校验角色权限
  if (to.meta.roles && !to.meta.roles.includes(userRole)) {
    next('/403') // 无权限跳转
  } else {
    next()
  }
})

登录状态深度校验

支持登录后自动跳转回目标页面,优化用户体验:

```javascript router.beforeEach((to, from, next) => { const token = localStorage.getItem('token') if (to.meta.requiresAuth && !token) { next(`/login?redirect=${encodeURIComponent(to.path)}`) // 保留目标路径 } else { next() } }) ```

异步权限校验(进阶)

守卫中处理异步请求(如API鉴权),需确保守卫完成后再放行:

```javascript router.beforeEach(async (to, from, next) => { if (to.meta.requiresAuth) { try { const res = await checkAuth() // 异步鉴权API if (res.valid) next() else next('/login') } catch (error) { next('/error') // 异常处理 } } else { next() } }) ```

动态管理

结合路由元信息(meta)实现标题动态渲染:

```javascript router.afterEach((to) => { const title = to.meta.title ? `${to.meta.title} - Vue App` : 'Vue Application' document.title = title }) ```

最佳实践与避坑指南

守卫性能优化

避免在守卫中执行耗时操作,异步逻辑需妥善处理:

```javascript // ❌ 错误示例:直接发起异步请求 router.beforeEach((to, from, next) => { fetch('/api/auth').then(() => next()) // 阻塞路由跳转 })

// ✅ 正确方案:异步守卫 + Promise处理 router.beforeEach(async (to, from, next) => { if (to.meta.requiresAuth) { await checkAuthAsync() // 返回Promise的校验函数 next() } })


<h4>守卫执行顺序控制</h4>
<p>全局守卫的执行链路:<code>beforeEach → 路由组件内守卫 →

标签: #js全局守卫 #文件位置