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

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

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

技术博主发布于 2026/4/8更新于 2026/7/2153 浏览
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 存储
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 基于 AR 眼镜的亲戚称呼助手开发实战
  • 动态规划入门:线性 DP 四道经典题解析
  • Git 多人协作全流程实战:分支协同与冲突解决
  • 27 岁自学 Python 转行可行性与入行时机分析
  • llama-cpp-python 本地部署与配置实战指南
  • 为什么要学习模型和方法论
  • Spring 事务注解及传播机制详解
  • AIOps 实践:基于 Dify 与 LangBot 集成飞书智能体
  • 二叉搜索树详解:概念、性能及 C++ 实现
  • 学习 Python 的 10 个核心理由
  • 模拟算法题详解:替换问号、提莫攻击、Z 字形变换、外观数列与数青蛙
  • ARIS 开源:基于 Claude Code 的全自动科研与论文工作流
  • Whisper-large-v3 离线部署实战:摆脱 HuggingFace Hub 的网络依赖
  • Google 秘密计划曝光:AI 或取代人类程序员敲代码
  • LeetCode 热题 100 快速通关指南与核心算法模板
  • 滑动窗口算法实战:最大连续 1 的个数 III 与将 x 减到 0 的最小操作数
  • Python 网络爬虫高级应用与 Scrapy 框架实战
  • Python Django Web 框架实战:构建产品管理系统
  • 飞算 JavaAI 插件安装与使用指南
  • 开源 IPTV 播放器 IPTVnator 功能解析与使用指南

相关免费在线工具

  • 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