vue-router 快速上手指南:用 Vue 2 + Vue Router 搭建你的第一个单页应用
2026/9/21 16:08:34 网站建设 项目流程
  • 前端
  • 路由

【免费下载链接】vue-router

🚦 The official router for Vue 2

项目地址:https://gitcode.com/gh_mirrors/vu/vue-router
点击查看免费下载

本篇指南以 vue-router(Vue 2 官方路由)的入门文档为核心,一步步带你完成从零搭建单页应用(SPA)的完整流程:引入依赖、定义路由组件、创建路由实例、挂载根实例,并理解router-linkrouter-viewthis.$routerthis.$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)。你只需要做三件事:

  1. 把组件定义出来(FooBar……);
  2. routes数组把路径和组件一一对应起来;
  3. 创建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模式使用HashHistoryhistory模式使用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.$routerthis.$route

注入路由之后,任意组件内都可以通过两个实例属性访问路由能力:

  • this.$router:路由实例,等同于new VueRouter(...)得到的router对象,用于执行导航pushreplacego等);
  • this.$route:当前激活的路由信息对象,包含pathparamsqueryhashfullPathmatchedname等字段,用于读取当前状态

官方入门文档给出的组件示例:

// 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.$routerrouter是同一个东西。之所以推荐在组件里用this.$router,是为了避免在每个需要路由的组件文件里手动 import 路由实例——通过 src/install.js 在Vue.prototype上定义的 getter,$router会向上查找到_routerRoot._router$route则返回_routerRoot._route,任何组件(包括深层子组件)都能直接拿到。

$route是响应式的:由于根实例的_routedefineReactive定义,当路由变化时(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 说明(toreplaceappendtagexactevent等),可参考 docs-gitbook/fr/api/router-link.md;更底层的渲染与点击拦截逻辑见 src/components/link.js。

结合源码看:一次点击导航的完整链路

把上面的知识串起来,当用户点击<router-link to="/bar">时,实际发生的调用链是:

  1. RouterLinkhandler(src/components/link.js)通过guardEvent拦截点击(拦截ctrl/meta/shift/alt组合键、右键、target="_blank"等情况,避免误导航),然后调用router.push(location)
  2. push(src/router.js)委托给当前history实现(hash 模式下更新 URL 的 hash 部分);
  3. history.transitionTo执行路由过渡,最终通过createMatchermatch()(src/create-matcher.js)按pathMap匹配到/bar对应的组件记录;
  4. history.listen回调更新根实例_route(src/router.js);
  5. 响应式系统通知<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

项目地址:https://gitcode.com/gh_mirrors/vu/vue-router
点击查看免费下载

相关推荐

上一篇:LittleFS软尾指针与硬尾指针:嵌入式文件系统的核心机制解析
下一篇:Platypus:把 Shell 和 Python 脚本打包成能双击启动的 macOS 应用

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询