【Vue Router】路由模式、懒加载、守卫、权限、缓存

前言

Vue Router 是 Vue 生态中处理页面跳转的核心工具,它解决了单页应用中 URL 管理、组件切换、状态维护等关键问题,同时提供了丰富的功能(如动态路由、嵌套路由、路由守卫)。除了经常用到的路由配置以外,我们还需了解以下几点。

1. Vue 路由模式

Vue Router 支持两种路由模式:

模式原理特点启用方式
Hash 模式使用 URL hash (#) 模拟完整 URL http://example.com/#/home兼容性好(支持 IE9) 无需服务器配置mode: 'hash' (默认)
History 模式基于 HTML5 History API http://example.com/homeURL 更美观 需要服务器端支持mode: 'history'

服务器配置示例 (History 模式):

# Nginx 配置
location / {try_files $uri $uri/ /index.html;
}

2. 路由懒加载

实现组件按需加载,提升首屏性能。

实现方式

const router = new VueRouter({routes: [// 魔法注释:webpackChunkName 定义分包名称{ path: '/dashboard',component: () => import(/* webpackChunkName: "dashboard"*/'./views/Dashboard.vue')},{path: '/user/:id',component: () => import(/* webpackChunkName: "user" */ './views/UserProfile.vue')}]
})

优化效果

  • 首屏加载时间减少 30-50%
  • 按路由拆分 chunk 文件
  • 支持预加载:<link rel="prefetch">

3. 路由缓存

使用 <keep-alive> 缓存组件状态:

<template><div id="app"><!-- 缓存带有 meta.keepAlive 的路由 --><keep-alive :include="cachedViews"><router-view v-if="$route.meta.keepAlive"></router-view></keep-alive><!-- 不缓存的路由 --><router-view v-if="!$route.meta.keepAlive"></router-view></div>
</template><script>
export default {computed: {cachedViews() {return this.$store.state.cachedRoutes}}
}
</script>

路由配置

{path: '/user/:id',component: UserDetails,meta: { keepAlive: true, // 启用缓存scrollPos: true  // 记录滚动位置}
}

可通过属性控制缓存范围:

  • include:仅缓存名称匹配的组件(组件需定义 name 属性)。
  • exclude:不缓存名称匹配的组件。
  • max:最多缓存的组件实例数量。

示例:

<keep-alive include="Home,About" :max="10"><router-view />
</keep-alive>

被缓存的组件会触发 activated(激活时)和 deactivated(失活时)生命周期钩子,替代 mountedunmounted

4. 路由守卫

守卫类型

// 1. 全局前置守卫
router.beforeEach((to, from, next) => {if (to.meta.requiresAuth && !isLoggedIn()) next('/login')else next()
})// 2. 路由独享守卫
{path: '/admin',beforeEnter: (to, from, next) => {checkAdminPermission() ? next() : next('/403')}
}// 3. 组件内守卫
const UserProfile = {beforeRouteEnter(to, from, next) {// 不能访问 thisnext(vm => console.log(vm.user)) // 通过回调访问组件实例},beforeRouteUpdate(to, from, next) {// 路由参数变化时触发this.fetchData(to.params.id)next()},beforeRouteLeave(to, from, next) {// 离开确认window.onbeforeunload = nullnext()}
}

1.全局路由

Route.beforeEeach 任意路由跳转前触发

Route.beforeResolve 导航确认前触发

Route.afterEach 导航完成后触发

2.路由独享守卫

beforeEnter 在路由配置上定义,进入路由时触发

3.组件内守卫

beforeRouteEnter 渲染组件路由被验证前调用(适合做进入前的权限验证,不能访问this)

beforeRouteUpdate 当组件路由改变,组件复用时候调用(适合在路由参数变化时重新加载数据

beforeRouteLeave 导航离开组件的对应路由时调用(适合做离开前的确认(如未保存的表单)

导航解析流程:

  • 1.触发导航 → 生成目标路由
  • 2.在失活的组件里调用(beforeRouteLeave
  • 3.执行 全局前置守卫beforeEach
  • 4.在重用的组件里调用beforeRouteUpdate
  • 5.执行 路由独享守卫beforeEnter
  • 6.执行 组件内前置守卫beforeRouteEnter
  • 7.解析异步路由组件:如 () => import('./User.vue')
  • 8.执行 组件内更新守卫beforeRouteUpdate,如适用)
  • 9.执行 组件内离开守卫beforeRouteLeave,如适用)
  • 10.执行 全局解析守卫beforeResolve
  • 11.确认导航,更新 URL 和路由记录
  • 12.执行 全局后置钩子afterEach
  • 13.Dom更新:销毁旧组件,创建并渲染新组件 → 完成导航

通过这个流程,Vue Router 实现了对路由导航的精细控制,结合不同类型的守卫可以满足权限验证、数据预加载、离开确认等多种业务需求。

5. 路由与后端菜单结合

动态路由工作流
在这里插入图片描述

实现代码

// 1. 定义基础路由(无需权限)
const constantRoutes = [{ path: '/login', component: Login },{ path: '/404', component: NotFound }
]// 2. 从后端获取菜单
async function initRoutes() {const menuData = await axios.get('/api/user/menus')const dynamicRoutes = generateRoutes(menuData)// 3. 动态添加路由dynamicRoutes.forEach(route => router.addRoute(route))// 4. 添加404捕获router.addRoute({ path: '*', redirect: '/404' })
}// 菜单转换函数
function generateRoutes(menuData) {return menuData.map(menu => ({path: menu.path,component: () => import(`@/views/${menu.component}`),meta: { title: menu.title, icon: menu.icon },children: menu.children ? generateRoutes(menu.children) : []}))
}

6. 路由权限控制

完整权限方案

// 权限检查函数
function hasPermission(route, roles) {if (route.meta?.roles) {return roles.some(role => route.meta.roles.includes(role))}return true // 无meta.roles则公开访问
}// 路由过滤
function filterRoutes(routes, roles) {return routes.filter(route => {if (hasPermission(route, roles)) {if (route.children) {route.children = filterRoutes(route.children, roles)}return true}return false})
}// 全局前置守卫
router.beforeEach(async (to, from, next) => {// 1. 获取用户角色const roles = store.getters.roles || []// 2. 白名单检查if (whiteList.includes(to.path)) return next()// 3. 未登录重定向if (!roles.length) return next(`/login?redirect=${to.path}`)// 4. 已登录但未初始化路由if (!store.getters.routesLoaded) {await initDynamicRoutes(roles) // 动态添加路由return next({ ...to, replace: true })}// 5. 检查目标路由权限if (!hasPermission(to, roles)) return next('/403')next()
})

按钮级权限控制

<template><button v-permission="'user:create'">添加用户</button>
</template>
// 权限指令
Vue.directive('permission', {inserted(el, binding) {const { value } = bindingconst permissions = store.getters.permissionsif (value && !permissions.includes(value)) {el.parentNode?.removeChild(el)}}
})

最佳实践总结

  1. 路由设计
    • 公共路由使用静态注册
    • 权限路由使用动态注册
    • 路由元信息存储权限标识
  2. 性能优化
    • 路由懒加载 + webpack 分包
    • 滚动行为恢复
    • 路由组件复用
  3. 安全控制
    • 前端路由权限校验
    • 后端接口二次验证
    • 按钮级权限控制
  4. 错误处理
    • 统一404处理
    • 403无权限页面
    • 路由切换错误捕获
// 错误捕获
router.onError(error => {console.error('路由错误:', error)if (/ChunkLoadError/.test(error.message)) {window.location.reload() // 重新加载解决chunk加载失败}
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/92637.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/92637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux epoll 实现详解 (fs/eventpoll.c)

核心数据结构分析 1. struct eventpoll (epoll 实例核心结构) c struct eventpoll {struct mutex mtx; // 保护 epoll 结构的互斥锁wait_queue_head_t wq; // epoll_wait() 使用的等待队列wait_queue_head_t poll_wait; // 文件 poll() 使用的等待队列struc…

【牛客刷题】小红的项链(字节跳动面试题)

文章目录 一、题目介绍 1.1 输入描述 1.2 输出描述 1.3 示例 二、算法设计思路 三、流程图 四、题解实现 五、复杂度分析 六、关键算法知识点 一、题目介绍 原题链接:https://www.nowcoder.com/practice/3da065cab096478eb603bbfca5af8b02 小红将 n n n个珠子排成一排,然后…

【Html网页模板】HTML炫酷星空(一闪一闪亮晶晶)

文章目录专栏导读功能预览快速开始核心实现拆解1. 背景与基础布局2. 背景层静态星空&#xff08;轻微闪烁&#xff09;3. 前景层“亮晶晶”的闪烁小星星4. 交互与动效5. 行星装饰可配置项与个性化建议初始化顺序&#xff08;入口&#xff09;源码结语专栏导读 &#x1f525;&am…

第一天-CAN Signal信号的Multiplexor多路复用在DBC中实现

&#x1f680; CAN总线的“变形金刚术”&#xff1a;Multiplexor多路复用信号深度揭秘在汽车电子江湖中&#xff0c;当数百个ECU争相发送数据时&#xff0c;如何让一条CAN报文像"变形金刚"一样自由切换形态&#xff1f;Multiplexor&#xff08;多路复用&#xff09;技…

Code Exercising Day 10 of “Code Ideas Record“:StackQueue part02

文章目录【150. Evaluate Reverse Polish Notation】【239. Sliding Window Maximum】【347. Top K Frequent Elements】【150. Evaluate Reverse Polish Notation】 Problem Link Approach: Use a stack. Push numbers onto the stack; when encountering an operator, pop t…

系统架构设计师备考之架构设计高级知识

1.系统架构设计基础知识1.1.软件架构概念软件架构定义软件架构&#xff08;Software Architecture&#xff09;或称软件体系结构&#xff0c;是指系统的一个或者多个结构&#xff0c;这些结构包括软件的构件&#xff08;可能是程序模块、类或者是中间件&#xff09;、构件的外部…

PWM波的频谱分析及matlab 验证[电路原理]

你知道吗&#xff1f;pwm可以制作adc模块哦&#xff01;这样普通的gpio也能实现adc功能了。 我们嵌入式日常接触的pwm波&#xff0c;你真的了解他吗&#xff1f; 只有知道PWM的频谱是怎么样的&#xff0c;才能设计合适的滤波器&#xff0c;下面我们一起从底层数学原理来推导PWM…

相机、镜头参数详解以及相关计算公式

一、工业相机参数 1、分辨率 相机每次采集图像的像素点数&#xff0c;也是指这个相机总共有多少个感光晶片。在采集图像时&#xff0c;相机的分辨率对检测精度有很大的影响&#xff0c;在对同样大的视场成像时&#xff0c;分辨率越高&#xff0c;对细节的展示越明显。 相机像素…

通信中间件 Fast DDS(一) :编译、安装和测试

目录 1.简介 2.Windows编译、安装和测试 2.1.编译环境准备 2.2.编译安装 2.2.1.安装FastCDR 2.2.2.安装Foonathan Memory 2.2.3.安装FastDDS 2.3.验证安装 3.Linux编译、安装和测试 3.1.编译环境准备 3.2.编译安装 3.2.1.安装FastCDR 3.2.2.安装Foonathan M…

NI USRP X410 无线电上的雷达目标仿真

此示例展示如何在 NI™ USRP™ 无线电的 FPGA 上部署雷达目标仿真算法。 介绍 在本例中&#xff0c;您将从 Simulink 模型入手&#xff0c;该模型可模拟最多四个雷达目标响应。您将按照分步指南&#xff0c;在 Simulink 中从该模型生成比特流&#xff0c;并使用生成的 MATLAB 主…

PyTorch 深度学习实战教程-番外篇04:卷积层详解与实战指南

标签&#xff1a;# 深度学习 #人工智能 #神经网络 #PyTorch #卷积神经网络 相关文章&#xff1a; 《Pytorch深度学习框架实战教程01》 《Pytorch深度学习框架实战教程02&#xff1a;开发环境部署》 《Pytorch深度学习框架实战教程03&#xff1a;Tensor 的创建、属性、操作与…

LeetCode 面试经典 150_数组/字符串_分发糖果(15_135_C++_困难)(贪心算法)

LeetCode 面试经典 150_数组/字符串_分发糖果&#xff08;15_135_C_困难&#xff09;题目描述&#xff1a;输入输出样例&#xff1a;题解&#xff1a;解题思路&#xff1a;思路一&#xff08;贪心算法&#xff09;&#xff1a;代码实现代码实现&#xff08;思路一&#xff08;贪…

配置timer控制 IO的输出(STC8)

使用STC8的Timer控制IO输出 STC8系列单片机具有多个定时器&#xff0c;可以用于精确控制IO口的输出状态。以下是使用Timer0和Timer1控制IO输出的方法。 初始化Timer0 配置Timer0为16位自动重装模式&#xff0c;用于周期性控制IO输出&#xff1a; /************************ 定时…

【Python练习】086. 编写一个函数,实现简单的DHCP服务器功能

086. 编写一个函数,实现简单的DHCP服务器功能 086. 编写一个函数,实现简单的DHCP服务器功能 安装依赖库 示例代码 代码说明 示例输出 注意事项 扩展功能 DHCP服务器功能实现方法 依赖库安装 基本功能实现 功能说明 运行方法 注意事项 扩展功能 086. 编写一个函数,实现简单的…

生产环境Tomcat运行一段时间后,如何测试其性能是否满足后续使用

要测试生产环境中已运行一段时间的Tomcat性能是否满足后续使用需求&#xff0c;需从基础监控、负载压力测试、配置合理性校验、稳定性验证等多维度入手&#xff0c;结合工具和实际业务场景定位瓶颈&#xff0c;确保其能应对未来可能的流量增长。以下是具体方法和步骤&#xff1…

Qt中的设计模式:经典的MVC,MVP和MVVM

Qt中的设计模式&#xff1a;经典的MVC&#xff0c;MVP和MVVM 前言 ​ 笔者这里最近正在研究经典的三大 Model/View 框架&#xff0c;不得不说&#xff0c;我先前的确写过Qt在这里的体现&#xff0c;但是&#xff0c;笔者认为之前的文章中&#xff0c;我只是机械的memcpy的Qt的…

Windows浮动ip怎么配置

Windows浮动IP怎么配置&#xff0c;达到IP漂移的效果&#xff0c;方法肯定是有的&#xff0c;这里我推荐一款好用的高可用Vip漂移软件PanguVip&#xff0c;我们先看下最终达到的效果图&#xff0c;如下所示PanguVip软件免费下载百度网盘为您提供文件的网络备份、同步和分享服务…

[langchain] Sync streaming vs Async Streaming

我不太清楚langchain中的sync stream 和 async steam有什么关系和区别sync stream from langchain.chat_models import init_chat_model from langchain_deepseek.chat_models import ChatDeepSeek import dotenv dotenv.load_dotenv()messages [ ("system", &quo…

nginx下lua的实现机制、Lua错误处理、面向对象

nginx下lua的实现机制 nginxlua概述 nginx&#xff1a;功能由模块提供。 http模块、events模块&#xff0c;mail模块。 处理http请求的时候&#xff0c;可以利用模块做一些功能&#xff1a;eg&#xff1a;登录校验&#xff0c;js合并&#xff0c;数据库访问&#xff0c;鉴权。 …

Axure基于中继器实现的组件库(导航菜单、动态表格)

摘要 本文将为您详细介绍基于 Axure 的中继器组件库中的 9 个独特组件&#xff0c;这些组件不仅能够极大地提升您的原型设计效率&#xff0c;还能为您的项目增添令人惊叹的交互效果和视觉呈现。 引言 在当今快速发展的数字产品设计领域&#xff0c;原型设计工具的革新不断推动着…