主题
mock首页需要数据 插件:mockjs与vue-echar(Day9 1/2)
本页对应 day9,共 6 段视频,约 1 小时 41 分。
学习目标
- 能根据登录后用户信息中的路由标识,说明菜单权限的实现流程,并验证不同账号获取到的路由标识不同。
- 能拆分静态路由、异步路由和任意路由三类,明确各类路由的用途及在菜单权限中的处理方式。
- 能编写递归过滤函数处理多级异步路由,仅保留用户路由标识命中的一级路由及其子路由,并验证子路由过滤结果正确回写到父路由。
- 能在获取用户信息后合并静态路由、过滤后的异步路由和任意路由生成左侧菜单,并使用
addRoute动态追加异步/任意路由,验证菜单点击后页面正常渲染。 - 能在退出登录时移除动态追加的异步/任意路由并保留静态路由,验证切换账号后不残留上一账号的菜单权限。
- 能使用
mockjs模拟首页所需数据,并在 Vue 组件中集成vue-echarts完成图表渲染与数据展示。
知识点
材料边界与本节目标
本节笔记标题写的是“mock首页需要数据 插件:mockjs”,但提供的转写稿实际记录的是“菜单权限业务实现”,没有出现 mockjs 的安装、配置或接口模拟代码,也没有图片。为避免编造,下面按转写稿整理菜单权限的实现过程;mockjs 部分因材料缺失不展开。转写稿中的“义步/亦步”即“异步”,“敞量”即“常量”,“秋君”即 children,“路游”即“路由”。
菜单权限要解决的核心问题是:不同账号登录后,用户信息里包含按钮标识和路由标识;左侧菜单由仓库中的 menuRoutes 决定,但浏览器能否访问某个路由,还取决于 router 是否注册了该路由。只改左侧菜单会出现“导航能看见、点进去空白”的问题。
路由为什么要拆成三类
为什么需要:所有人登录都要有登录页、首页、404 等路由;权限管理、商品管理等路由则因职位不同而不同;还要有兜底路由。
怎么想:把路由拆成常量路由、异步路由、任意路由。常量是大家都有的,异步是“有的人有、有的人没有”,任意路由负责兜底。
怎么做:按转写稿整理,路由拆分示意如下:
ts
// 变量名按转写稿口述整理
export const constantRoutes = [login, home, 404]
export const asyncRoutes = [ACL, product]
export const anyRoutes = { /* 任意路由对象 */ }易错点:不要把首页、登录页、404 放进异步路由;不要把任意路由当成普通异步路由;拆分的目的是后面能按用户信息过滤异步路由,再与常量、任意路由合并。
异步路由过滤:递归后必须赋值
为什么需要:用户信息返回的是路由组件 name 标识,可能包含一级,也可能包含二级。异步路由有层级,不能只判断一级。
怎么想:用 filter 遍历异步路由;当前路由 name 在用户路由标识数组中出现才保留;如果它有 children,还要递归过滤子路由。
怎么做:转写稿中的关键逻辑是“递归过滤后要重新赋值给 children”:
ts
function filterAsyncRoutes(asyncRoutes, userRoutes) {
return asyncRoutes.filter(item => {
if (userRoutes.includes(item.name)) {
if (item.children && item.children.length > 0) {
item.children = filterAsyncRoutes(item.children, userRoutes)
}
return true
}
return false
})
}易错点:只判断一级、不递归二级;递归结果没有赋值回去;直接修改原始 asyncRoutes 会污染后续账号的过滤结果。转写稿调试时专门打印过过滤结果,并强调“过滤出来的新数组要赋值给 item.children”,否则二级仍然原样保留。
左侧菜单合并与动态注册路由
为什么需要:左侧菜单应显示“常量路由 + 当前用户过滤后的异步路由 + 任意路由”。同时,router 初始只注册了常量路由,不动态追加,点击菜单会空白。
怎么想:先根据用户信息过滤异步路由,再合并生成 menuRoutes;然后对异步路由和任意路由执行 addRoute。
怎么做:
ts
const filteredAsyncRoutes = filterAsyncRoutes(asyncRoutes, userRoutes)
menuRoutes = [...constantRoutes, ...filteredAsyncRoutes, anyRoutes]
[...asyncRoutes, anyRoutes].forEach(route => {
router.addRoute(route)
})易错点:anyRoutes 在转写稿中是对象,不是数组,合并时不要盲目展开;只改 menuRoutes 不 addRoute,会出现导航存在但页面空白;动态追加应在获取用户信息之后执行。
退出登录重置与调试顺序
为什么需要:老板账号登录后注册了全部异步路由,退出后换上海账号登录,如果不清空,上一个账号的路由会残留,导致上海账号也能访问老板权限。
怎么想:退出登录时移除当前用户的异步、任意路由,保留常量路由,保证登录页还能进入;下一个用户登录时重新计算、重新追加。
怎么做:转写稿思路是根据路由名移除非常量路由,再重新注册常量路由:
ts
router.getRoutes().forEach(route => {
if (!constantRoutes.some(item => item.name === route.name)) {
router.removeRoute(route.name)
}
})
constantRoutes.forEach(route => router.addRoute(route))易错点:不能把路由全清,否则连登录页都回不去;不能只清左侧菜单不清 router;调试时按“打印用户信息里的路由标识 → 打印过滤结果 → 看 router.getRoutes() 是否只有常量 → 加 addRoute → 切换账号验证残留”的顺序排查。转写稿正是通过这条顺序定位到“菜单有了但路由没注册”和“退出未重置”两个问题。
先说明:本节笔记与转写稿不一致
本节笔记只有两条信息:
- echarts 插件可用于 angular、react、vue;
- vue-echarts 是 Vue 框架下的插件。
但转写稿实际讲的是“菜单权限业务实现”:按钮权限、异步路由过滤、常量路由/异步路由/任意路由拆分、addRoute 动态追加路由、退出登录清理路由等。它并不是 vue-echarts 的使用讲解。因此,不能把转写稿里的菜单权限推导硬套成 vue-echarts 教程,否则就是编造。
另外,本节笔记没有图片,也没有代码;所以不存在需要保留的图片和代码。转写稿中的同音字可纠正为:案钮→按钮、义步/亦步→异步、常量→常量、路游→路由、守位→守卫、秋君→children、肉特→route、addRoute→动态追加路由。但这些属于菜单权限内容,不应写进 vue-echarts 的知识点。
echarts 为什么需要框架插件
为什么需要:echarts 本身是图表库,核心是配置项驱动渲染;但在 Vue、React、Angular 这类框架里,页面由组件和生命周期管理,如果每次都手写 DOM 初始化、更新、销毁,代码会重复且容易漏掉清理。
怎么想:笔记先写“echarts 插件:angular、react、vue”,说明 echarts 不是只服务某一个框架,而是有不同框架的适配方式;到 Vue 项目里,就对应 vue-echarts。
怎么做:在 Vue 项目中把 vue-echarts 作为插件/组件适配层接入,让图表以 Vue 组件方式使用,而不是在业务组件里散落原生初始化代码。
易错点:不要把“echarts”和“vue-echarts”混为一谈。echarts 是图表能力本身,vue-echarts 是 Vue 侧的插件适配;也不要把 React、Angular 的用法直接搬到 Vue。
vue-echarts 的定位:Vue 框架插件
为什么需要:Vue 项目强调声明式和组件化。如果图表不能作为组件使用,模板结构、状态更新和销毁逻辑都会变得零散。
怎么想:笔记写“vue-echarts:vue 框架[插件]”,关键词是“Vue 框架”和“插件”。这说明它的定位不是替代 echarts,而是让 echarts 在 Vue 里按插件方式接入。
怎么做:按 Vue 项目的插件注册方式接入 vue-echarts,然后在组件中使用图表组件,把 echarts 配置项交给它渲染。具体注册名、组件名和配置写法应以所用 Vue 版本对应的官方文档为准,本节笔记没有给出代码,不能补写具体 API。
易错点:不要凭记忆写未经验证的组件名或配置字段;不同 Vue 版本、不同 vue-echarts 版本的接入方式可能不同。没有代码依据时,教程应说明“按官方文档接入”,而不是编造示例。
使用思路:配置项驱动与容器约束
为什么需要:图表最终要落到一个容器里显示,而 echarts 的显示效果主要由配置项决定。Vue 组件化后,配置项通常作为组件输入,数据变化时再更新。
怎么想:先确认“图表库负责画图,Vue 插件负责把画图能力组件化”;再确认容器必须有可计算的宽高,否则图表没有绘制区域。
怎么做:在 Vue 组件中准备图表容器,接入 vue-echarts 后传入配置项;数据变化时更新配置;组件卸载时确保图表实例被清理。由于本节笔记没有具体代码,这里只讲通用思路,不写虚构代码。
易错点:容器没有高度是最常见的“图表不显示”原因;重复初始化会导致实例叠加;卸载不清理可能造成内存泄漏。调试时应先看容器尺寸,再看配置项是否传入,最后看实例是否重复创建。
与转写稿的边界:不要把菜单权限当成 vue-echarts
为什么需要:转写稿大量出现“按钮权限、异步路由、addRoute、退出登录清空路由”等内容,如果直接拿来补本节,会把“路由权限”误写成“图表插件使用”。
怎么想:判断知识点归属:vue-echarts 解决的是 Vue 中如何使用 echarts;菜单权限解决的是不同用户能看到哪些菜单和路由。两者不是同一主题。
怎么做:本节只保留笔记已有事实:echarts 支持 angular/react/vue,vue-echarts 是 Vue 框架插件;转写稿中的菜单权限推导应另立“菜单权限业务实现”教程。
易错点:不要为了凑字数把 addRoute、异步路由递归过滤、退出登录清理路由写进 vue-echarts;也不要编造本节笔记没有的图片和代码。若后续要写菜单权限,应单独整理,并把“按钮、异步路由、常量路由、路由守卫、children、route、addRoute”等同音字纠正清楚。
课堂画面






代码示例
常见错误
- 现象:切换账号后仍能看到上一账号的菜单,甚至能访问其路由。原因:退出登录只清了 token/userInfo,未移除动态
addRoute注册的路由。修法:退出时按记录的动态路由name调用removeRoute,仅保留常量路由;重新登录后重算并重新注册。 - 现象:左侧有菜单,点击后右侧空白。原因:只合并了
menuRoutes用于渲染菜单,未把异步/任意路由动态注册到 router。修法:过滤结果与任意路由逐个addRoute,并记录待移除的name。 - 现象:第二个账号过滤结果缺路由,或前一个账号的路由被改坏。原因:递归过滤时直接修改原异步路由数组/
children。修法:过滤函数返回新数组/新对象,children用map/filter生成新引用,不污染源数据。 - 现象:退出后登录页/404 打不开,或无法重新登录。原因:清理动态路由时把常量路由也
removeRoute了。修法:只移除动态追加项,常量路由始终保留。 - 现象:某账号该出现的菜单不出现。原因:后端返回的路由标识与
route.name大小写/拼写不一致,或一级有children时未递归匹配。修法:统一name契约;先匹配一级,再递归children并回填新children。 - 现象:mock 首页请求 404 或空数据。原因:mock 未在入口注册,或接口路径与请求不一致。修法:入口引入 mock,统一 baseURL/路径,在控制台确认请求被拦截。
- 现象:vue-echarts 图表空白。原因:组件未按文档注册,或容器高度为 0。修法:按插件文档注册,容器设明确宽高,数据更新后触发 resize。
练习
- 实现
filterAsyncRoutes(routes, routeNames):返回新路由树,支持一级/二级匹配,且不修改入参。 - 在获取用户信息成功后,合并常量路由、过滤后的异步路由、任意路由,生成左侧菜单并动态注册,记录注册的路由
name。 - 实现退出登录清理:移除动态路由、保留常量路由、清 token/userInfo,并验证切换账号不串权。
- 用“超级管理员”和“平台管理员”两个账号做验证清单:左侧菜单、直接输 URL、刷新、退出再登录。
- 给首页接口加 mock,并用 vue-echarts 渲染一个图表;要求接口无数据时有空态,图表容器有明确高度。
原视频对照
| # | 视频 | 时长 |
|---|---|---|
| 1 | 菜单权限业务实现1 | 19:23 |
| 2 | 菜单权限业务实现2 | 22:35 |
| 3 | 异步路由递归进行过滤 | 28:29 |
| 4 | 菜单权限业务的完成 | 11:23 |
| 5 | 菜单权限业务完成动态追加路由addRoute | 10:48 |
| 6 | 解决菜单问题1 | 09:08 |
小结
- 菜单权限和路由注册是两条线:菜单决定“看得见”,
addRoute决定“进得去”。 - 路由拆常量/异步/任意,是权限计算、动态注册和退出清理的基础。
- 异步路由过滤必须是纯函数,避免账号间数据污染。
- 动态注册必须可追踪、可移除;退出登录只清动态项,常量路由不能动。
route.name是前后端权限标识契约,命名一致性应优先排查。- 验证必须覆盖切账号、刷新、直输 URL、退出再登录四类场景。
- mock 与图表问题优先查注册、路径、容器高度,不要先怀疑框架。