路由是什么?

路由(routing)就是通过互联的网络把信息从源地址传输到目的地址的活动。

摘自 wikipedia

打个比方,我们要访问谷歌的官网。从我们的计算机到发出请求,到谷歌服务器这中间发生的所有的工作,都可以被称为路由。

而在前端开发中,通常我们所讨论的路由指的是框架根据你的 URL,转接到特定的处理模块,此期间发生的工作。

http://example.com/about/contact.html

比如以上是一个常见的 URL, /about/contact.html 部分被称为路径。从传统的前端意义下来说,这里路径意思就是网站的 根目录 下的 about 文件夹内的 contact.html 文件。 此时的 URL 路径跟与处理模块的文件路径是一致的。

有时我们不想 URL 路径与处理模块的文件路径保持一致,我们可以通过配置路由来指定处理的模块,这便是路由映射,属于前端路由的基本功能。

举个小小的例子,体现了路由映射 的好处。如果我们想访问公司名为三眼鸭下地区为北京下员工 id 为123 的员工页面。在传统的前端开发中,我们必须将 URL 路径写成。

http://example.com/user.html?company=三眼鸭&region=北京&id=123

这种传统的 URL 路径需要在后面接一长串的查询参数,而且由于查询参数都是同级的,无法表示父子关系,我们就不能理解是员工 id 为123在北京地区下的三眼鸭公司,还是三眼鸭公司的北京分公司下的员工 id 为123。

对于现代化的前端框架,路由功能使得我们对于 URL 路径的定义灵活性就高了许多。对于以上需求我们通常会定义成以下的形式。

http://example.com/company/三眼鸭/region/北京/user/123

这样子路径就清晰了起来,父子关系也很明确。先去找公司名三眼鸭,再去找其下的地区北京,最后找其下员工 id 为 123 的页面,并且老古董 .html 后缀也可以去掉了。

通过路由映射功能,使得我们可以灵活定义 URL 路径,路径与处理模块的文件路径无需保持一致。

再举个知乎的例子。

https://www.zhihu.com/question/496642056/answer/2206396661

以上的这个 URL 路径就表示了,question id 为 496642056,其下的 answer id 为 2206396661 的回答。

路由的原理

对于一些现代化的前端框架来说,它们会要求所有的路径都要指向同一个入口文件(多数是 index.html)。如此一来框架就能拦截所有的请求, 再自行处理选择哪个模块来响应页面请求,实现中间件、路由映射、路由参数管理等高级功能。

使得所有路径指向同一个入口文件的方式一般是两种:

  • Hash 模式
  • Nginx 等反向代理工具

可以参考文章Hash 与 HTML5 模式的机制来简单理解路由拦截请求的原理。

Vue Router 是什么?

Vue Router 就是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

  • 嵌套路由映射
  • 动态路由选择
  • 模块化、基于组件的路由配置
  • 路由参数、查询、通配符
  • 展示由 Vue.js 的过渡系统提供的过渡效果
  • 细致的导航控制
  • 自动激活 CSS 类的链接
  • HTML5 history 模式或 hash 模式
  • 可定制的滚动行为
  • URL 的正确编码

Vue Router 的学习

有关 Vue Router 的学习最好的方式就是查阅其官方文档,文档里已经包含各式各样的使用场景与配置方法。

上手 Vue Router

以下以一个简单的示例,带大家上手 Vue Router。

假设你已创建一个 Vue3 的项目,可以跟随以下步骤使用 Vue Router。

  1. 安装 Vue Router
  2. 创建页面
  3. 配置 Vue Router
  4. 挂载 Vue Router

安装 Vue Router

通过 npm 安装 Vue Router 的 4.x 最新版本。

npm install vue-router@4

创建页面

在项目的 src 文件夹中新建 pages 文件夹用于保存页面文件,内新建两个页面文件 Home.vueAbout.vue

image

Home.vue:

<template>
    <h1>首页</h1>
    <!-- 链接至 name 为 about 的页面 -->
    <!-- name 在绑定路由时设置 -->
    <router-link :to="{ name: 'about' }">跳转关于页面</router-link>
</template>

About.vue:

<template>
    <h1>关于页面</h1>
    <!-- 链接至 name 为 home 的页面 -->
    <!-- name 在绑定路由时设置 -->
    <router-link :to="{ name: 'home' }">跳转首页</router-link>
</template>

配置 Vue Router

src文件夹中新建 router 文件夹,内新建 index.js 文件夹存放 router 的配置。

配置中使用的是 HTML5 历史记录模式,可以查阅官方文档进行理解,并参阅另一篇文章 Hash 与 HTML5 模式的机制

import * as VueRouter from "vue-router"

import Home from "@/pages/Home.vue"
import About from "@/pages/About.vue"

const routes = [
    {
        name: "home", // 页面名
        path: "/", // 映射的路径
        component: Home, // 虽配置名为 component 组件,但我更愿意理解为 page 页面
    },
    {
        name: "about",
        path: "/about",
        component: About,
    },
]

const router = VueRouter.createRouter({
    // 使用 HTML5 模式
    history: VueRouter.createWebHistory(),
    routes,
})

export default router

$$tip 使用 HTML5 模式需要进行相关的服务器配置,可以参考官方文档中对于 HTML5 模式的服务器配置示例。 $$

挂载 Vue Router

修改 App.vue 文件,添加 <router-view></router-view> ,删除其他不必要的代码。

App.vue 便是我们的入口页面,不管 URL 路径如何总是会加载 App.vue 页面。然后再通过 <router-view></router-view> 显示路由根据当前路径匹配到的组件(页面) 。

<template>
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-view></router-view>
</template>

修改 main.js 文件挂载 Vue Router。

import { createApp } from "vue"
import App from "./App.vue"
import router from "./router"

const app = createApp(App)
// 挂载 router
app.use(router)
app.mount("#app")

如此便完成了一个 Vue Router 实现的最简单实例,可以 npm run dev 运行实例进行测试。