7.1 Vue Router 基础:地址到组件 本节摘要:Vue Router 的核心是一张"路径模式到组件"的映射表,配上一个渲染出口。本节覆盖静态路由、动态参数、嵌套路由三种形态,讲清两种历史模式的原理差异与部署后果,以及编程式导航与传参的三种方式。 学习目标 阅读完本节,你应当能够: 独立配置含动态段与嵌套层的路由表; 解释 hash 与 history 两种模式的实现差异及服务器配置要求; 按场景选择传参方式:动态段、查询串、状态对象; 用命名路由加命名视图组织复杂布局。 一、最小路由系统 路由系统三件套:映射表、出口、导航触发。 router-link 渲染出的确实是原生 a 标签(利于 SEO 与可访问性),但点击被拦截,转成路由内部的导航——不发请求、不刷页面,只是组件切换。
本节摘要:Vue Router 的核心是一张"路径模式到组件"的映射表,配上一个渲染出口。本节覆盖静态路由、动态参数、嵌套路由三种形态,讲清两种历史模式的原理差异与部署后果,以及编程式导航与传参的三种方式。
阅读完本节,你应当能够:
路由系统三件套:映射表、出口、导航触发。
import { createRouter, createWebHistory } from 'vue-router'; const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component: Home }, { path: '/about', component: About } ] }); app.use(router);
<!-- 出口:匹配到的组件渲染在这里 --> <router-view></router-view> <!-- 触发:渲染成 a 标签,但拦截默认跳转 --> <router-link to="/about">关于</router-link>
router-link 渲染出的确实是原生 a 标签(利于 SEO 与可访问性),但点击被拦截,转成路由内部的导航——不发请求、不刷页面,只是组件切换。这就是单页应用"换页"的真相。
路径里的动态段用冒号声明:
{ path: '/user/:id', component: User, props: true }
// 组件内取参(Vue 3 组合式) import { useRoute } from 'vue-router'; const route = useRoute(); route.params.id; // 声明了 props: true 后参数直接进 props,组件更纯净 defineProps(['id']);
props: true 这个细节值得养成习惯:组件从 props 拿参数而不是直接摸路由对象,组件就能脱离路由环境复用与测试。Vue 2 里对应 this.$route.params.id,同理可用函数式 props 解耦。
同一路径参数变化时(id 从 1 到 2),组件会复用而不重建——这是第 4 章 vnode 复用逻辑在路由层的体现。副作用是 watch 参数才响应变化:
watch(() => route.params.id, (newId) => { fetchUser(newId); // 复用场景下的数据刷新正位 });
忘了 watch 的典型症状:从用户列表点进详情正常,在详情页内点"下一个用户"界面不动——组件没重建,挂在 created 里的请求自然没跑。
后台管理系统的经典布局——侧边栏常驻,主区域换内容——用嵌套路由表达最自然:
{ path: '/admin', component: AdminLayout, // 布局组件:侧边栏 + <router-view> children: [ { path: 'users', component: UserList }, // /admin/users { path: 'settings', component: Settings } // /admin/settings ] }

AdminLayout 内部再放一个 router-view,子路由渲染在那里。切换子路由时布局组件不动、只有内容区换——布局层被复用了,管线只更新出口位置。子路径不加前导斜杠是关键(加了就变成绝对路径),这是新手配置错误第一名。
hash 模式:地址形如 /#/user。原理是修改 location 的 hash 片段——hash 变化不发请求、触发 hashchange 事件,路由据此切换。零服务器配置,天生可用。
history 模式:地址干净(/user)。原理是 history.pushState 改地址不发请求,前进后退靠 popstate。代价在刷新与直达:用户直接访问 example.com/user 时,服务器真会收到这个路径的请求,必须配置成一律返回入口页(SPA 回退),否则 404。
选型实际很直接:能改服务器配置(Nginx 加一条回退规则)就用 history,URL 干净对分享与 SEO 都好;静态托管改不了配置就 hash。Vue 3 项目里两者各一行:createWebHashHistory 对 createWebHistory。
router.push('/user/5'); // 路径串 router.push({ name: 'user', params: { id: 5 } }); // 命名路由(推荐) router.back(); // 历史
传参三种方式按语义选:
| 方式 | 示例地址 | 适合 | 特点 |
|---|---|---|---|
| 动态段 | /user/5 | 资源身份 | 刷新后仍在,可分享 |
| 查询串 | /search?q=vue | 筛选、分页条件 | 刷新仍在,键值可多 |
| 状态对象 | push 时附带 state | 列表页回跳位置 | 不出现在地址,刷新即丢 |
永远优先命名路由而不是硬编码路径字符串——路径改版时,命名路由改一处配置,字符串散落各处的改法是重构噩梦。
再补一个初学者几乎必踩的部署坑做记忆锚点:本地开发一切正常,部署到服务器后 history 模式的应用一刷新就 404,很多人第一反应是"代码坏了"。其实本地开发时 Vite 的开发服务器自带了回退逻辑替你兜着,上线后没人兜底而已。理解了两种模式的原理差异(7.1 第四节),这类问题的定位是秒级的;不理解原理,就只能把报错贴到搜索引擎碰运气。同理,嵌套路由子路径多写一个斜杠导致匹配失败、动态路由参数变化页面不动,这些高频坑的排查都依赖你对"路由即组件切换"这个模型的掌握程度。
基础的映射讲完,下一节进入路由最有力也最容易失控的部分——守卫链与权限。