跳至内容

入门

Vue Router 是 Vue 的官方客户端路由解决方案。

客户端路由由单页应用程序 (SPA) 使用,将浏览器 URL 绑定到用户看到的內容。当用户在应用程序中导航时,URL 会相应更新,但页面不需要从服务器重新加载。

Vue Router 基于 Vue 的组件系统构建。您配置 **路由** 以告知 Vue Router 为每个 URL 路径显示哪些组件。

先决条件

本指南假设您已经熟悉 Vue 本身。您不需要是 Vue 专家,但您可能偶尔需要参考 Vue 核心文档 以获取有关某些功能的更多信息。

一个例子

为了介绍一些主要思想,我们将考虑这个例子

让我们从查看根组件 App.vue 开始。

App.vue

vue
<template>
  <h1>Hello App!</h1>
  <p>
    <strong>Current route path:</strong> {{ $route.fullPath }}
  </p>
  <nav>
    <RouterLink to="/">Go to Home</RouterLink>
    <RouterLink to="/about">Go to About</RouterLink>
  </nav>
  <main>
    <RouterView />
  </main>
</template>

此模板使用 Vue Router 提供的两个组件,RouterLinkRouterView

我们使用自定义组件 RouterLink 来创建链接,而不是使用常规的 <a> 标签。这使 Vue Router 能够在不重新加载页面的情况下更改 URL,处理 URL 生成、编码以及其他各种功能。我们将在本指南的后面部分详细介绍 RouterLink

RouterView 组件告诉 Vue Router 在哪里渲染当前的 **路由组件**。这是与当前 URL 路径相对应的组件。它不必在 App.vue 中,您可以将其放在任何地方以适应您的布局,但它确实需要包含在某个地方,否则 Vue Router 不会渲染任何内容。

上面的示例还使用 {{ $route.fullPath }}。您可以在组件模板中使用 $route 来访问表示当前路由的对象。

Vue Mastery Logo 获取来自 Vue Mastery 的 Vue Router 速查表

创建路由实例

路由实例是通过调用函数 createRouter() 创建的

js
import { createMemoryHistory, createRouter } from 'vue-router'

import HomeView from './HomeView.vue'
import AboutView from './AboutView.vue'

const routes = [
  { path: '/', component: HomeView },
  { path: '/about', component: AboutView },
]

const router = createRouter({
  history: createMemoryHistory(),
  routes,
})

routes 选项定义路由本身,将 URL 路径映射到组件。component 选项指定的组件是将在我们之前 App.vue 中的 <RouterView> 中渲染的组件。这些路由组件有时被称为视图,尽管它们只是普通的 Vue 组件。

路由支持各种其他选项,我们将在本指南的后面部分看到,但现在我们只需要 pathcomponent

history 选项控制路由如何映射到 URL 以及反之亦然。对于 Playground 示例,我们使用 createMemoryHistory(),它完全忽略浏览器 URL 并使用自己的内部 URL。这对于 Playground 来说效果很好,但它不太可能是您在真实应用程序中想要的。通常,您希望使用 createWebHistory(),或者可能是 createWebHashHistory()。我们将在本指南中更详细地介绍 历史模式 的主题。

注册路由插件

创建路由实例后,我们需要通过在应用程序上调用 use() 来将其注册为插件

js
createApp(App)
  .use(router)
  .mount('#app')

或者,等效地

js
const app = createApp(App)
app.use(router)
app.mount('#app')

与大多数 Vue 插件一样,对 use() 的调用需要在对 mount() 的调用之前进行。

如果您好奇这个插件的作用,它的一些职责包括

  1. 全局注册 RouterViewRouterLink 组件。
  2. 添加全局 $router$route 属性。
  3. 启用 useRouter()useRoute() 组合式 API。
  4. 触发路由以解析初始路由。

访问路由和当前路由

您可能希望从应用程序的其他地方访问路由。

如果您从 ES 模块导出路由实例,则可以直接在需要的地方导入路由实例。在某些情况下,这是最佳方法,但如果我们在组件内部,我们还有其他选择。

在组件模板中,路由实例以 $router 的形式公开。这类似于我们之前看到的 $route 属性,但请注意末尾的额外 r

如果我们使用选项 API,我们可以在 JavaScript 代码中以 this.$routerthis.$route 的形式访问这两个属性。Playground 示例中的 HomeView.vue 组件以这种方式访问路由

js
export default {
  methods: {
    goToAbout() {
      this.$router.push('/about')
    },
  },
}

此方法调用 push(),用于 编程导航。我们将在后面学习更多关于它的内容。

使用组合式 API,我们无法通过 this 访问组件实例,因此 Vue Router 包含一些组合式 API,我们可以使用它们。Playground 示例中的 AboutView.vue 使用了这种方法

vue
<script setup>
import { computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'

const router = useRouter()
const route = useRoute()

const search = computed({
  get() {
    return route.query.search ?? ''
  },
  set(search) {
    router.replace({ query: { search } })
  }
})
</script>

现在不必理解所有这些代码。需要注意的关键是,组合式 API useRouter()useRoute() 分别用于访问路由实例和当前路由。

下一步

如果您想查看使用 Vite 的完整示例,可以使用 create-vue 脚手架工具,它可以选择在示例项目中包含 Vue Router

bash
npm create vue@latest
bash
yarn create vue
bash
pnpm create vue

create-vue 创建的示例项目使用了与我们在此处看到的类似的功能。您可能会发现它是一个有用的起点,可以用来探索本指南接下来的几页中介绍的功能。

本指南中的约定

单文件组件

Vue Router 最常用于使用捆绑器(例如 Vite)和 SFC(即 .vue 文件)构建的应用程序。本指南中的大多数示例都将以这种方式编写,但 Vue Router 本身并不需要您使用构建工具或 SFC。

例如,如果您使用的是 VueVue Router全局构建,则这些库通过全局对象公开,而不是导入

js
const { createApp } = Vue
const { createRouter, createWebHistory } = VueRouter

组件 API 风格

Vue Router 可以与 Composition API 和 Options API 一起使用。在相关的情况下,本指南中的示例将展示以两种风格编写的组件。Composition API 示例通常会使用 <script setup>,而不是显式的 setup 函数。

如果您需要关于这两种风格的复习,请参阅 Vue - API 风格

routerroute

在整个指南中,我们经常将路由器实例称为 router。这是 createRouter() 返回的对象。您在应用程序中访问该对象的方式将取决于上下文。例如,在使用 Composition API 的组件中,可以通过调用 useRouter() 来访问它。使用 Options API,可以通过使用 this.$router 来访问它。

类似地,当前路由将被称为 route。它可以通过使用 useRoute()this.$route 在组件中访问,具体取决于组件使用的是哪个 API。

组件 RouterViewRouterLink全局注册,因此在组件模板中使用它们之前不需要导入它们。但是,如果您愿意,可以本地导入它们,例如 import { RouterLink } from 'vue-router'

在模板中,组件名称可以写成 PascalCase 或 kebab-case。Vue 的模板编译器支持两种格式,因此 <RouterView><router-view> 通常是等效的。您应该遵循项目中使用的任何约定。

如果您使用的是 DOM 内模板,那么 通常的注意事项 适用:组件名称必须写成 kebab-case,并且不支持自闭合标签。因此,您需要使用 <router-view></router-view> 而不是 <RouterView />