跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端

Vue Router 进阶实战:导航守卫、嵌套路由与状态管理

Vue Router 进阶实战详解,涵盖导航守卫的权限校验逻辑、嵌套路由的层级结构设计以及 Hash 与 History 模式的适用场景。通过路由元信息配合全局守卫实现灵活控制,并结合 Pinia 状态管理库完成数据持久化方案,为单页应用提供从路由配置到状态维护的完整技术参考。

技术博主发布于 2026/4/8更新于 2026/10/23113 浏览
Vue Router 进阶实战:导航守卫、嵌套路由与状态管理

深入使用

导航守卫

在路由跳转前、跳转后或解析过程中,我们往往需要插入自定义逻辑,比如权限验证或页面埋点。理解 to(目标路由)、from(当前离开的路由)和 next(控制函数)是掌握守卫的关键。

  • next():继续执行路由。
  • next(false):中断当前导航,如果浏览器 URL 已改变,则回退到 from 路由。
  • next('/path'):跳转到指定路径。
  • next(error):将控制权交给 router.onError()。
组件内守卫

当路由进入特定组件时,可以在组件内部定义生命周期钩子:

export default {
  beforeRouteEnter(to, from, next) {
    // 在路由进入前调用,此时组件实例尚未创建
    next();
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变但组件复用时调用
    next();
  },
  beforeRouteLeave(to, from, next) {
    // 在路由离开前调用
    next();
  }
};
路由独享守卫

直接在路由配置中定义,适用于单个路由的独立逻辑:

const routes = [
  {
    path: '/admin',
    component: Admin,
    beforeEnter: (to, from, next) => {
      if (isAdmin()) {
        next();
      } else {
        next('/login');
      }
    }
  }
];
全局守卫

全局前置守卫 beforeEach 是最常用的入口,适合做登录态校验;后置钩子 afterEach 不接收 next,常用于统计或日志记录;而 beforeResolve 在所有组件内守卫和异步路由解析完成后调用,适合处理最终权限确认。

// 全局前置守卫
router.beforeEach((to, from, next) => {
  if (to.path === '/protected' && !isLoggedIn()) {
    next('/login');
  } else {
    next();
  }
});

// 全局后置钩子
router.afterEach((to, from) => {
  console.log('路由已切换');
  // 例如:记录日志或者统计页面访问等
});

嵌套路由

构建层级页面结构时,嵌套路由非常实用。父组件模板中需包含 <router-view> 来渲染子路由:

<template>
  <div>
    <h2>用户页面</h2>
    <router-view></router-view>
  </div>
</template>

定义时注意,以 / 开头的嵌套路径被视为根路径,这允许利用组件嵌套而不必强制嵌套 URL。官方文档对此有更详细的说明:Vue Router 嵌套路由。

const routes = [
  {
    path: '/user',
    component: User,
    children: [
      { path: 'profile', component: UserProfile },
      { path: 'posts', component: UserPosts }
    ]
  }
];

重定向与别名

重定向通过 routes 配置完成。需注意,重定向不会触发目标路由的守卫,除非目标路由本身有守卫。别名则不同,它只是映射 URL,URL 保持不变。

相对重定向示例:

const routes = [
  {
    path: '/users/:id/posts',
    redirect: to => to.path.replace(/posts$/, 'profile')
  }
];

别名常用于 UI 结构与 URL 解耦。例如,让 /people 和 /list 都指向同一个列表组件:

const routes = [
  {
    path: '/users',
    component: UsersLayout,
    children: [
      {
        path: '',
        component: UserList,
        alias: ['/people', 'list']
      }
    ]
  }
];

history 配置:指定历史模式

Vue Router 支持三种历史模式,选择取决于项目需求:

  1. Hash 模式 (createWebHashHistory):默认模式,URL 带 #,无需服务器配置,适合纯前端 SPA,但 SEO 效果一般。
  2. History 模式 (createWebHistory):URL 更简洁,无 #,但需要服务器配置回退到 index.html,适合对 SEO 有要求的项目。
  3. Memory 模式 (createMemoryHistory):不与 URL 交互,适合 Node 环境或 SSR。注意它没有历史记录,无法后退或前进,需在 app.use(router) 后手动 push 初始导航。

路由元信息(meta)

在路由配置中添加 meta 字段,可存储权限标识、页面标题等数据,配合全局守卫实现灵活控制。

const routes = [
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: Dashboard,
    meta: { requiresAuth: true, title: '控制面板' }
  }
];

在组件中可通过 useRoute().meta 获取这些信息。

拓展

状态管理(Pinia / Vuex)

对于复杂或跨页面的数据传递,推荐使用状态管理库。Vuex 是 Vue 官方的经典方案,采用 Flux 思想,核心包括 State、Getters、Mutations 和 Actions。Pinia 则是 Vue 3 推荐的新一代方案,设计更现代化,完美支持 Composition API,且去除了 Mutations 概念,直接使用 Actions 修改状态。

Pinia 基本使用

结合插件 pinia-plugin-persistedstate 可实现数据持久化。

安装依赖:

npm install pinia pinia-plugin-persistedstate

初始化 Store:

import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  getters: {
    doubleCount(state) {
      return state.count * 2;
    }
  },
  actions: {
    increment() {
      this.count++;
    }
  },
  persist: {
    enabled: true,
    storage: window.localStorage
  }
});

在 main.ts 中启用持久化插件:

import { createPinia } from 'pinia';
import { createPersistedState } from 'pinia-plugin-persistedstate';

const pinia = createPinia();
pinia.use(createPersistedState());
app.use(pinia);
Pinia 使用 Cookies 存储

虽然 Cookie 容量有限,但在某些场景下仍可用于简单持久化。使用时需手动处理读写逻辑:

export const useUserStore = defineStore('user', {
  state: () => ({ name: null, age: null }),
  actions: {
    setName(name) {
      this.name = name;
      document.cookie = `name=${name}; path=/; max-age=3600`;
    },
    getName() {
      const row = document.cookie.split('; ').find(r => r.startsWith('name='));
      if (row) this.name = row.split('=')[1];
    }
  }
});

这种组合方式既利用了 Pinia 的响应式优势,又满足了特定的存储需求。

目录

  1. 深入使用
  2. 导航守卫
  3. 组件内守卫
  4. 路由独享守卫
  5. 全局守卫
  6. 嵌套路由
  7. 重定向与别名
  8. history 配置:指定历史模式
  9. 路由元信息(meta)
  10. 拓展
  11. 状态管理(Pinia / Vuex)
  12. Pinia 基本使用
  13. Pinia 使用 Cookies 存储

更多推荐文章

查看全部
  • OpenDroneMap 无人机影像处理与地理数据生成指南
  • Go Web 开发基础:模板引擎与控制器实战
  • 推荐一位拥有七年经验的互联网运营从业者
  • 基于 Docker 部署 Jenkins 与 Playwright 实现 Web 自动化测试
  • Claude Code vs GitHub Copilot CLI 终端开发深度评测
  • GitHub 项目上传实战指南
  • 动态规划路径类 DP 入门:最小路径和、迷雾森林与过河卒
  • OpenClaw 开源桌面 Agent 部署与飞书钉钉集成实战指南
  • 利用腾讯云 HAI 与 DeepSeek 快速构建个人网页
  • 基于腾讯云 HAI 与 DeepSeek 快速构建个人网页
  • ROS1 全局参数:定义、获取与修改实战
  • 本地电脑训练专属大模型实战教程
  • Java JDK 安装与环境配置教程(Windows + macOS 通用)
  • SpringBoot3 + OpenSpec 实现 MCP 服务器实践
  • C++ 手写 JSON 与 HTTP Web 服务器实战
  • 金仓数据库 Oracle 与 SQL Server 迁移适配指南
  • GitHub Copilot Pro 学生认证免费获取详细指南
  • WebEx Player:播放.wrf 格式会议录制文件的官方方案
  • Spring Web 模块核心概念与基础架构解析
  • 斯坦福 Octopus v2:端侧运行大模型性能超越 GPT-4

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online