一句话总结
hash 模式路由在 # 后(# 不发给服务器,无需服务端配置,兼容好但 URL 丑、SEO 弱);history 模式用真实路径(好看,靠 pushState/replaceState + popstate,刷新必须服务端兜底到 index.html)。导航守卫是路由跳转的拦截链,beforeEach 里做 token 鉴权;状态管理选 Pinia(Vue3 官方推荐:无 mutation、完整 TS 推导、组合式写法)。
初级理解
| 对比项 | hash | history |
|---|---|---|
| URL 形态 | /#/user?id=1 | /user?id=1 |
| 底层 API | hashchange 事件 | pushState / replaceState + popstate |
| 服务端配置 | 不需要 | 需要(404 兜底) |
| 刷新 | 永远请求 /,安全 | 请求真实路径,未配置则 404 |
| 锚点功能 | 冲突(# 被占用) | 正常 |
编程式导航:router.push()(保留历史)、replace()(替换当前记录,登录后常用)、go(-1)。传参两种:query(?id=1,刷新不丢)和 params(路径段 /user/:id,Vue Router 4 中 push 的 params 不带路径名会被丢弃——刷新即丢,别再用它传关键数据)。
Vuex vs Pinia 一句话:Vuex 是 state/getter/mutation/action 五件套,改数据必须经 mutation(同步);Pinia 砍掉 mutation,action 里直接改,天然支持 TS 和组合式 store。
中级深入
完整的导航解析流程(守卫执行顺序):
守卫三件套记忆:全局(beforeEach/beforeResolve/afterEach)、路由级(beforeEnter)、组件级(beforeRouteEnter/Update/Leave)。beforeEach 的三个参数 (to, from, next)——Vue Router 4 也支持返回值风格:return false 取消、return 路径重定向、不返回则放行。
路由懒加载:把组件编译成独立 chunk,进入时才加载:component: () => import('./views/User.vue')。这是首屏优化的标配(配合 webpackChunkName/vite 的 rollupOptions 注释分包)。
高级拓展
动态路由与按钮级权限:登录后按接口返回的菜单表 router.addRoute() 动态注册路由(前端只留静态基础路由);按钮级权限用自定义指令或组件包裹判断权限码。
history 模式的 Nginx 配置(生产必背):
Pinia 组合式 store 与持久化:defineStore 里可以像 setup 一样写 ref/computed/函数;持久化用 pinia-plugin-persistedstate(localStorage),或手动 watch 同步——token 这类敏感信息建议只放 sessionStorage 或内存,避免 XSS 读取。
实战场景
场景一:登录鉴权 + 白名单
场景二:刷新后动态路由丢失
场景三:多标签页(Tab)系统缓存路由组件
面试模拟
Q:history 模式刷新 404 的原因和解决方案?
A:history 的路径是真实 HTTP 请求,服务器上并没有 /user/a/1 这个文件,所以 404。解决:Nginx try_files $uri $uri/ /index.html 兜底到单页入口;Node 服务则配历史回退中间件。注意回退会掩盖真实的资源 404,要给静态资源目录单独的 location。
Q:为什么 Vue3 生态从 Vuex 迁到 Pinia?
A:Pinia 的改进点:① 去掉 mutation——同步异步都在 action,模板字符串式的 commit 消失;② 完整 TS 类型推导(Vuex 的类型推导一直很弱);③ 天然支持组合式写法和代码分割(每个 store 独立文件按需引入);④ 模块化天然扁平,不用 modules 嵌套命名空间;⑤ Vue 作者直接维护、devtools 支持。Vuex 官方也建议新项目用 Pinia。
Q:beforeRouteEnter 里为什么拿不到 this?怎么解决?
A:守卫执行时组件实例还没创建(导航确认在前、挂载在后),this 是 undefined。官方给的口子是 next 回调:beforeRouteEnter(to, from, next) { next(vm => console.log(vm)) },在 DOM 更新后执行且唯一支持传实例。Vue Router 4 里也可改用 onBeforeRouteUpdate/onBeforeRouteLeave 组合式 API(它们在 setup 内执行,天然能访问响应式上下文;注意 onBeforeRouteEnter 不存在,组件内进入钩子仍用 beforeRouteEnter)。