- 前端
- 路由
【免费下载链接】vue-router
🚦 The official router for Vue 2
本篇指南以 vue-router(Vue 2 官方路由)的入门文档为核心,一步步带你完成从零搭建单页应用(SPA)的完整流程:引入依赖、定义路由组件、创建路由实例、挂载根实例,并理解router-link、router-view、this.$router与this.$route四大核心概念。读完后你将能独立写出一个可运行的"组件 ↔ 路由"映射应用,并理解其底层工作原理,为后续学习嵌套路由、动态路由匹配、导航守卫等进阶能力打下基础。
为什么用 Vue + Vue Router 就能做单页应用
创建单页应用(Single Page Application)的思路是:整个页面只加载一次,后续"页面跳转"不再触发浏览器整页刷新,而是由 JavaScript 动态替换页面中的局部内容。在 Vue 的世界里,页面本身就是由组件构成的,所以"跳转"本质上就是在同一个<div id="app">内,根据当前 URL 换掉渲染的组件。
Vue Router 恰好就是负责这层"URL ↔ 组件"映射关系的官方路由库(本仓库package.json中描述为"Official router for Vue.js 2",当前版本为 3.6.5)。你只需要做三件事:
- 把组件定义出来(
Foo、Bar……); - 用
routes数组把路径和组件一一对应起来; - 创建
VueRouter实例并注入 Vue 根实例,剩下的渲染交给路由完成。
源码层面,VueRouter类的构造函数(src/router.js)接收options后,会用createMatcher(options.routes || [], this)(src/create-matcher.js)把routes编译成一张路径/名称匹配表;根实例beforeCreate时调用this._router.init(this)(见 src/install.js)完成首次路由过渡。对使用者来说,这些细节都可以先不关心,按下面的步骤即可跑起来。
说明:本文示例按官方入门文档采用 ES2015 语法书写;同时示例使用的是 Vue 的完整版(包含模板编译器),以便直接解析
template字符串。若使用运行时构建(runtime-only),则需要配合单文件组件(.vue)或渲染函数。本仓库示例(如 examples/basic/app.js)正是用字符串模板 +$mount('#app')的方式运行的。
第一步:引入 Vue 与 Vue Router
方式一:CDN 引入(最简单的演示方式)
在 HTML 中按顺序引入两个脚本,vue-router必须在vue之后加载:
<script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>使用全局<script>标签时,vue-router会自动完成安装(VueRouter.install被调用,见 src/router.js 中window.Vue存在时自动window.Vue.use(VueRouter)的逻辑),无需手动调用Vue.use()。unpkg.com提供基于 npm 的 CDN 链接,上面的地址始终指向 npm 上的最新版本;也可以锁定具体版本,例如https://unpkg.com/vue-router@3.6.5/dist/vue-router.js。
方式二:npm 安装 + 模块系统
npm install vue-router通过模块系统(如 vue-cli 生成的项目)使用时,必须显式调用Vue.use(VueRouter)完成插件安装:
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter)Vue.use()会触发 src/install.js 中的install函数,它做了三件关键的事:
- 通过
Vue.mixin注入beforeCreate钩子,使每个组件都能访问路由实例与当前路由; - 在
Vue.prototype上定义$router和$route两个响应式属性(后面会讲); - 全局注册
<router-link>与<router-view>两个组件(Vue.component('RouterView', View)/Vue.component('RouterLink', Link))。
如果想使用仓库最新的开发构建,可以克隆本仓库到node_modules/vue-router后自行编译(详见 docs-gitbook/fr/installation.md):
git clone https://github.com/vuejs/vue-router.git node_modules/vue-router cd node_modules/vue-router npm install npm run build第二步:编写 HTML 骨架——两个魔法组件
在页面中放置#app容器,里面只放两个 Vue Router 提供的全局组件:
<div id="app"> <h1>Bonjour l'application !</h1> <p> <!-- 使用 router-link 组件进行导航 --> <!-- 通过向 `to` prop 传入目标路径来指定链接 --> <!-- <router-link> 默认会被渲染为 <a> 标签 --> <router-link to="/foo">Aller à Foo</router-link> <router-link to="/bar">Aller à Bar</router-link> </p> <!-- router-view 出口 --> <!-- 与当前路由匹配的组件会被渲染在这里 --> <router-view></router-view> </div>这两个组件是整个 SPA 的骨架,职责分工明确:
<router-link>:导航链接。指定toprop 后,点击它会触发路由跳转,而不是浏览器的整页刷新。默认渲染为<a>标签,href由路由自动计算。<router-view>:渲染出口。当前路由匹配到的组件会被渲染在这个位置。其实现(src/components/view.js)是一个函数式组件,通过parent.$route获取当前路由,再按嵌套深度取route.matched[depth]对应的组件进行渲染;没有匹配时渲染空节点(h())。
第三步:编写 JavaScript——五步完成路由装配
官方入门示例把整个装配过程拆成编号步骤,逐段来看:
// 0. 如果使用模块系统(例如通过 vue-cli),需要先导入 Vue 和 Vue Router,并调用 Vue.use(VueRouter)。 // (使用全局 script 标签时此步可省略,见上文) // 1. 定义路由组件。 // 这些组件也可以从其他文件导入。 const Foo = { template: '<div>foo</div>' } const Bar = { template: '<div>bar</div>' } // 2. 定义路由。 // 每条路由都必须对应一个组件。「组件」可以是 // 通过 Vue.extend() 创建的真实组件,也可以只是一个 // 选项对象(options object)。 // 嵌套路由我们稍后再讨论。 const routes = [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ] // 3. 创建路由实例并传入 `routes` 选项。 // 还可以传入其他选项,但这里先保持简单。 const router = new VueRouter({ routes // 等价于 `routes: routes` }) // 4.(官方示例中省略了此编号,保持原注释顺序) // 5. 创建并挂载 Vue 根实例。 // 确保通过 `router` 选项注入路由,这样 // 整个应用才能感知到路由变化。 const app = new Vue({ router }).$mount('#app') // 应用已经跑起来了!每一步在源码中的对应
- 第 1 步:路由组件可以是
Vue.extend()构造的组件,也可以直接是包含template的普通选项对象(如上例)。官方注释特别强调这一点,因为路由配置非常灵活。 - 第 2 步:
routes数组中的每一条记录都会在createRouteMap(见 src/create-route-map.js)中被编译为路由记录(route record),并建立pathMap(路径 → 记录)与nameMap(命名路由 → 记录)两张查找表,供后续match()使用。 - 第 3 步:
new VueRouter({ routes })内部(src/router.js)还会根据options.mode选择历史实现:默认hash模式使用HashHistory,history模式使用HTML5History,非浏览器环境自动降级为abstract模式。入门阶段不传mode即可,使用默认的 hash 模式(URL 形如/#/foo)。 - 第 5 步:根实例的
router选项是关键。在 src/install.js 的beforeCreate钩子中,检测到this.$options.router存在时,会把它保存为_routerRoot并执行this._router.init(this),同时用Vue.util.defineReactive把_route定义为响应式属性——这正是"URL 变化 →router-view自动更新"的响应式基础。
这个完整流程与仓库示例完全一致,可对照 examples/basic/app.js(使用
mode: 'history'的完整版示例)以及其页面模板 examples/basic/index.html 查看真实可运行代码。
第四步:在任何组件中访问路由——this.$router与this.$route
注入路由之后,任意组件内都可以通过两个实例属性访问路由能力:
this.$router:路由实例,等同于new VueRouter(...)得到的router对象,用于执行导航(push、replace、go等);this.$route:当前激活的路由信息对象,包含path、params、query、hash、fullPath、matched、name等字段,用于读取当前状态。
官方入门文档给出的组件示例:
// Home.vue export default { computed: { username () { // 稍后会看到 `params` 代表什么(动态路由参数) return this.$route.params.username } }, methods: { goBack () { window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/') } } }这个例子展示了两种典型用法:
- 读取:
this.$route.params.username读取当前路由的动态参数(与/user/:username这类动态路由配合使用,详见 docs-gitbook/fr/essentials/dynamic-matching.md); - 导航:
goBack()根据window.history.length判断,有历史记录就this.$router.go(-1)后退一步,否则this.$router.push('/')回首页。
为什么文档中有时直接用router,有时用this.$router
官方文档在很多地方会直接使用router实例,请记住:this.$router与router是同一个东西。之所以推荐在组件里用this.$router,是为了避免在每个需要路由的组件文件里手动 import 路由实例——通过 src/install.js 在Vue.prototype上定义的 getter,$router会向上查找到_routerRoot._router,$route则返回_routerRoot._route,任何组件(包括深层子组件)都能直接拿到。
$route是响应式的:由于根实例的_route被defineReactive定义,当路由变化时(src/router.js 中history.listen会逐个更新所有 app 的_route),所有依赖$route的组件(如computed: { username })都会自动重新计算。这也是"单页、无刷新、数据自动更新"体验的来源。
第五步:认识默认激活样式.router-link-active
官方入门文档最后强调了一个很容易被忽略的细节:
当
<router-link>的目标路由与当前路由匹配时,它会自动获得.router-link-active类。
也就是说,导航菜单高亮不需要你手动维护"当前是哪个链接",Vue Router 会自动加上这个类,配合一行 CSS 即可实现"当前页高亮"效果。
其实现位于 src/components/link.js:RouterLink渲染时通过router.resolve()得到目标路由,然后计算两个类:
router-link-active:包含式匹配——当前路由只要"包含/前缀匹配"目标路由就激活(例如目标/foo,当前/foo/bar也算激活);router-link-exact-active:精确匹配——仅在当前路由与目标路由完全相同时激活(Vue Router 2.5.0+ 新增)。
两个类的默认名称都可以在路由选项中全局覆盖(linkActiveClass/linkExactActiveClass),也可以在单个链接上用active-class/exact-active-classprop 覆盖。关于router-link的完整 prop 说明(to、replace、append、tag、exact、event等),可参考 docs-gitbook/fr/api/router-link.md;更底层的渲染与点击拦截逻辑见 src/components/link.js。
结合源码看:一次点击导航的完整链路
把上面的知识串起来,当用户点击<router-link to="/bar">时,实际发生的调用链是:
RouterLink的handler(src/components/link.js)通过guardEvent拦截点击(拦截ctrl/meta/shift/alt组合键、右键、target="_blank"等情况,避免误导航),然后调用router.push(location);push(src/router.js)委托给当前history实现(hash 模式下更新 URL 的 hash 部分);history.transitionTo执行路由过渡,最终通过createMatcher的match()(src/create-matcher.js)按pathMap匹配到/bar对应的组件记录;history.listen回调更新根实例_route(src/router.js);- 响应式系统通知
<router-view>(src/components/view.js)重新渲染,把Bar组件渲染到出口位置。
至此,一次"点击链接 → URL 变化 → 组件切换"的 SPA 导航闭环就完成了。仓库中的 e2e 测试(如 test/e2e/specs/basic.js)对这类交互有完整断言,可以作为行为参考。
下一步往哪走
入门文档只是一个起点。围绕本仓库,你可以继续深入:
- 动态路由匹配:
/user/:id这类带参数的路由,对应$route.params的使用:docs-gitbook/fr/essentials/dynamic-matching.md; - 嵌套路由:路由与组件层级嵌套,配合多级
<router-view>:docs-gitbook/fr/essentials/nested-routes.md; - 编程式导航:
router.push/router.replace/router.go的完整用法:docs-gitbook/fr/essentials/navigation.md; - History 模式:去掉 URL 中的
#,需要服务端配合:docs-gitbook/fr/essentials/history-mode.md; - 导航守卫:在导航前后拦截与校验:docs-gitbook/fr/advanced/navigation-guards.md。
仓库的 examples 目录还提供了几十个可直接运行的示例(入口为 examples/server.js,npm run dev即可启动),其中 examples/basic 就是本入门指南的完整可运行版本。
- 前端
- 路由
【免费下载链接】vue-router
🚦 The official router for Vue 2
相关推荐
Vue Router 2 快速上手:用 vue-router 构建你的第一个 Vue.js 单页应用
Vue Router 2 快速上手:用 vue router 构建你的第一个 Vue.js 单页应用 本文是 Vue Router 官方文档 "Primeros
前端路由Rocket.Chat 的 Meteor 现代构建栈(Modern Build Stack):文件监听原理、Watchman 冲突排查与 TurboRepo 子进程问题全解析
Rocket.Chat 的 Meteor 现代构建栈(Modern Build Stack):文件监听原理、Watchman 冲突排查与 TurboRepo 子
前端路由RPCS3汉化教程:3步把PS3模拟器界面改成中文,乱码问题一次讲清
RPCS3汉化教程:3步把PS3模拟器界面改成中文,乱码问题一次讲清 RPCS3 是一款在电脑上运行 PS3 游戏的模拟器,官方界面默认是英文。这篇教程带你把它
前端路由
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考