如何使用 Vue 路由器在视图之间导航

作者选择了 开源精神疾病以作为 写给捐赠计划的一部分获得捐赠。

介绍

大多数网站或应用程序都有多个 HTML页面,这些页面是静态或动态生成的。 更传统的网站有一个 Document Object Model (DOM)]和每个URL路线的页面。 然而,在 single-page applications 中,每个页面或视图都在一个HTML页面中进行渲染。 用户界面(UI)框架如Vue.js在使用虚拟DOM时将这些页面和组件渲染。

当用户访问单页应用程序时,该应用程序会将自己与虚拟 DOM 进行比较,并仅重新渲染被更改的网页部分。此技术防止网页在点击链接时闪烁白色。假设网页上有三个部分:标题、内容和脚印。

在 Vue.js 中,您可以使用第一方图书馆 Vue Router创建多个视图。 该路由器会创建一个与 URL 视图的关联。 在本教程中,您将学习如何添加 Vue Router 图书馆,将其集成到您的项目中,并创建动态生成的路径。 您还将学习开发人员可用的不同类型的路由器。 完成后,您将有一个应用程序,您可以使用各种方法导航。

为了说明这些概念,您将创建一个小型应用程序,显示机场信息. 当用户点击机场地图时,该应用程序将导航到机场的详细信息的动态视图。

前提条件

要完成本教程,您将需要:

步骤 1 – 设置样本应用程序

您要建立的应用程序来学习Vue Router将需要一些初始数据. 在此步骤中,您将创建和结构这些数据,以便在教程中稍后可访问您的Vue应用程序。

要添加此数据集,您需要创建一个数据目录,并创建一个名为airports.js的JavaScript文件。

1cd src

然后创建一个数据目录:

1mkdir data

现在创建一个data/airports.js文件,并在文本编辑器中打开它。

添加以下内容来为您的应用程序创建数据:

 1[label airport-codes/src/data/airports.js]
 2export default [
 3  {
 4    name: 'Cincinnati/Northern Kentucky International Airport',
 5    abbreviation: 'CVG',
 6    city: 'Hebron',
 7    state: 'KY',
 8      destinations: {
 9      passenger: [ 'Toronto', 'Seattle/Tacoma', 'Austin', 'Charleston', 'Denver', 'Fort Lauderdale', 'Jacksonville', 'Las Vegas', 'Los Angeles', 'Baltimore', 'Chicago', 'Detroit', 'Dallas', 'Tampa' ],
10        cargo: [ 'Anchorage', 'Baltimore', ' Chicago' , 'Indianapolis', 'Phoenix', 'San Francisco', 'Seattle', 'Louisville', 'Memphis' ]
11      }
12  },
13  {
14    name: 'Seattle-Tacoma International Airport',
15    abbreviation: 'SEA',
16    city: 'Seattle',
17    state: 'WA',
18      destinations: {
19      passenger: [ 'Dublin', 'Mexico City', 'Vancouver', 'Albuquerque', 'Atlanta', 'Frankfurt', 'Amsterdam', 'Salt Lake City', 'Tokyo', 'Honolulu' ],
20        cargo: [ 'Spokane', 'Chicago', 'Dallas', ' Shanghai', 'Cincinnati', 'Luxenbourg', 'Anchorage', 'Juneau', 'Calgary', 'Ontario' ]
21      }
22  },
23  {
24    name: 'Minneapolis-Saint Paul International Airport',
25    abbreviation: 'MSP',
26    city: 'Bloomington',
27    state: 'MN',
28      destinations: {
29      passenger: [ 'Dublin', 'Paris', 'Punta Cana', 'Winnipeg', 'Tokyo', 'Denver', 'Tulsa', 'Washington DC', 'Orlando', 'Mexico City' ],
30        cargo: [ 'Cincinnati', 'Omaha', 'Winnipeg', 'Chicago', 'St. Louis', 'Portland', 'Philadelphia', 'Milwaukee', 'Ontario' ]
31      }
32  }
33]

这些数据是由美国几个机场组成的 objectsarray 。 在此应用程序中,您将通过这些数据进行迭代,生成由名称缩写城市属性组成的卡片。当用户点击地图时,您将将其路由到Vue Router的动态视图中,并从其中一个属性中读取。

保存和退出文件。

接下来,在名为视图的目录中创建一个Home.vue组件,您可以通过打开终端并使用mkdirtouch命令创建该目录和组件。

运行以下命令来创建目录:

1mkdir views

然后创建Home.vue文件:

1touch views/Home.vue

Home.vue组件将作为此应用程序的首页,您将利用v-for指令重复通过airports.js数据集,并在地图上显示每个机场。

在「Home.vue」中添加以下代码:

 1[label airport-codes/src/views/Home.vue]
 2<template>
 3  <div class="wrapper">
 4    <div v-for="airport in airports" :key="airport.abbreviation" class="airport">
 5      <p>{{ airport.abbreviation }}</p>
 6      <p>{{ airport.name }}</p>
 7      <p>{{ airport.city }}, {{ airport.state }}</p>
 8    </div>
 9  </div>
10</template>
11
12<script>
13import { ref } from 'vue'
14import allAirports from '@/data/airports.js'
15
16export default {
17  setup() {
18    const airports = ref(allAirports)
19    	return { airports }
20    }
21}
22</script>
23
24<style>
25#app {
26  font-family: Avenir, Helvetica, Arial, sans-serif;
27  -webkit-font-smoothing: antialiased;
28  -moz-osx-font-smoothing: grayscale;
29  text-align: center;
30  color: #2c3e50;
31  margin-top: 60px;
32}
33.wrapper {
34  display: grid;
35  grid-template-columns: 1fr 1fr 1fr;
36  grid-column-gap: 1rem;
37  max-width: 960px;
38  margin: 0 auto;
39}
40.airport {
41  border: 3px solid;
42  border-radius: .5rem;
43  padding: 1rem;
44}
45.airport p:first-child {
46  font-weight: bold;
47  font-size: 2.5rem;
48  margin: 1rem 0;
49}
50.airport p:last-child {
51  font-style: italic;
52  font-size: .8rem;
53}
54</style>

Home.vue组件中,你正在重复一个集合的机场,每一个都被分配给一个CSS类机场。这个CSS通过编写边界来为生成的HTML添加一些风格,使每个机场看起来像一张卡片。

保存并关闭文件。

现在,您已经与本地数据集一起创建了此初始视图,您将在下一步安装Vue Router。

步骤2:安装Vue路由器

如果您正在使用 Vue CLI创建一个新的项目,您可以在提示中选择 Vue Router;Vue CLI将为您安装并配置它。

要安装 Vue Router,首先从src目录返回项目目录的根:

1cd ..

然后在项目的根目录中的终端窗口中运行下列操作:

1npm i vue-router@next

由于这个项目正在使用 Vue 3 和 Composition API,你正在告诉 npm 下载该库的最新实验版本. 如果你想了解有关当前版本的更多信息,请参阅 Vue Router 在 GitHub 上发布页面

这将从 npm 下载vue-router库并将其添加到您的package.json文件中,以便下次运行npm install时自动下载。

下一步是创建你的路线文件. 此文件将包含用户可以导航的所有可能的路线. 当 URL 栏中访问特定路线时,与 URL 路线相关的组件将安装。

在您的终端中,在src目录中,进入src目录并创建一个路由器目录:

1cd src
2mkdir router

接下来,在路由器目录中创建一个index.js文件:

1touch router/index.js

打开您刚刚创建的文件到您所选择的编辑器中。 首先要做的是导入Vue Router库. 您实际上不需要访问该库中的所有内容以创建路径。 您可以选择摧毁(https://andsky.com/tech/tutorials/understanding-destructuring-rest-parameters-and-spread-syntax-in-javascript)或只导入您所需要的内容以最大限度地减少包的大小。 在这种情况下,您需要从Vue Router中使用两种功能:分别是CreateWebHistoryCreateRouter。 这些功能创建了一个历史,用户可以返回并构建Vue的路由器对象。

将下列代码添加到 router/index.js:

1[label airport-codes/src/router/index.js]
2import { createWebHistory, createRouter } from "vue-router"

接下来,添加以下突出的行来创建和导出路由器:

1[label airport-codes/src/router/index.js]
2import { createWebHistory, createRouter } from "vue-router"
3
4const router = createRouter({
5  history: createWebHistory(),
6})
7
8export default router

该文件将导航器对象从CreateRouter函数返回出口。您传输的对象有两个属性:历史路线历史属性包含从CreateWebHistory生成的历史,路线是对象的组合。您将在本教程中稍后添加路线

接下来,导入首页视图并创建一个对象组,将它们存储在一个名为路径构件中:

 1[label airport-codes/src/router/index.js]
 2import { createWebHistory, createRouter } from "vue-router"
 3import Home from "@/views/Home.vue"
 4
 5const routes = [
 6  {
 7    path: "/",
 8    name: "Home",
 9    component: Home,
10  },
11]
12
13const router = createRouter({ ... })
14
15export default router

每个路径都是一个具有三个属性的对象:

  • path: URL 地址
  • name:在您的项目中引用路线的指定的名称
  • component: 在浏览器 URL 栏中输入 path 时安装的组件

现在你的路径数组已经创建,你需要将其添加到导出的路由器对象中。

历史键/值对后,添加路线,这是JavaScript中的路线:路线的缩写:

 1[label airport-codes/src/router/index.js]
 2import { createWebHistory, createRouter } from "vue-router"
 3
 4const routes = [ ... ]
 5
 6const router = createRouter({
 7  history: createWebHistory(),
 8  routes
 9})
10
11export default router

在此时,Vue Router 已集成到您的项目中,您已注册一条路线. 保存并退出文件。

在另一台终端中,运行以下命令,在本地机器上启动开发服务器:

1npm run serve

如果您在浏览器窗口中访问localhost:8080/,则您将不会看到Home.vue组件,此整合过程的最后一步是告诉 Vue 倾听这个router/index.js文件,并注入安装的组件,其中<router-view />被引用。

首先,打开src/main.js,然后添加以下突出的行:

1[label airport-codes/src/main.js]
2import { createApp } from 'vue'
3import App from './App.vue'
4import router from './router'
5
6createApp(App).use(router).mount('#app')

使用这个链接到createApp.use()函数,Vue.js 现在正在收听路由变更并利用您的src/router/index.js文件,但是,Vue Router 无法显示安装的Home.vue组件。 要做到这一点,您需要在您的App.vue文件中添加router-view组件。

保存并退出 main.js 文件。

接下来,打开App.vue文件,删除默认内容,并用以下内容替换:

1[label airport-codes/src/App.vue]
2<template>
3  <router-view />
4</template>

保存和退出文件。

现在,请访问您的浏览器中的localhost:8080/ 您将看到Home.vue组件的渲染,如下图所示:

Three cards displaying information about airports, retrieved from the data/airports.js file.

在下一节中,您将创建额外的路线,包括两个内部页面和默认 ** 404**页面,如果没有路线被检测到。

步骤三:创建内部页面

在此时,您的App.vue可以返回您在src/router/index.js文件中配置的任何组件。在使用Vue CLI生成的项目时,为您创建的目录之一是Views。此目录包含任何.vue组件,这些组件直接地图到router/index.js文件中的路线。重要的是要注意,这不是自动完成的。您需要创建一个.vue导入到您的路由器文件中,以便注册,如上所述。

在您定义所有其他路线之前,您可以创建一个默认路线. 在本教程中,此默认路线将作为一个 404 - Not Found页面 - 如果没有路线,则会出现倒退。

首先,创建将作为 404页面的视图。

1cd views

然后创建一个名为PageNotFound.vue的文件:

1touch PageNotFound.vue

在您的文本编辑器中,打开您刚刚创建的这个 PageNotFound.vue 文件. 添加以下 HTML 代码,以便为视图提供一些可渲染的内容:

1[label airport-codes/src/views/PageNotFound.vue]
2<template>
3  <div>
4    <h1>404 - Page Not Found</h1>
5    <p>This page no longer exists or was moved to another location.</p>
6  </div>
7</template>

保存并关闭文件。

现在已经创建了PageNotFound.vue组件,现在是时候为您的应用程序创建一个全路径了。

 1[label airport-codes/src/router/index.js]
 2import { createWebHistory, createRouter } from "vue-router"
 3import Home from "@/views/Home.vue"
 4import PageNotFound from '@/views/PageNotFound.vue'
 5
 6const routes = [
 7  {
 8    path: "/",
 9    name: "Home",
10    component: Home,
11  },
12  {
13    path: '/:catchAll(.*)*',
14    name: "PageNotFound",
15    component: PageNotFound,
16  },
17]
18...

Vue Router for Vue 3 使用了自定义 RegEx。‘路径’的值包含这个新的 RegEx,它告诉 Vue 为每个路径渲染‘PageNotFound.vue’,除非路径已经定义。

保存此文件,并访问您的应用程序在您的浏览器窗口在localhost:8080/not-found。你会发现PageNotFound.vue组件在您的浏览器中渲染,如下图像所示:

A 404 page that tells the user that the page they are looking for has not been found.

请自由地将此URL更改为其他任何东西;您将获得相同的结果。

在继续之前,为您的应用程序创建另一个路线. 该路线将是一个关于**页面。

打开您选择的终端并在视图目录中创建文件:

1touch About.vue

在文本编辑器中,打开您刚刚创建的About.vue文件,添加以下HTML来创建有关您的网站的更多信息:

1[label airport-codes/src/views/About.vue]
2<template>
3  <div>
4    <h1>About</h1>
5    <p>This is an about page used to illustrate mapping a view to a router with Vue Router.</p>
6  </div>
7</template>

保存并关闭文件。

通过创建此视图,在文本编辑器中打开src/router/index.js文件,导入About.vue组件,并注册一个新的路径,其路径为/about:

 1[label airport-codes/src/router/index.js]
 2import { createWebHistory, createRouter } from "vue-router"
 3import Home from '@/views/Home.vue'
 4import About from '@/views/About.vue'
 5import PageNotFound from '@/views/PageNotFound.vue'
 6
 7...
 8const routes = [
 9  {
10    path: "/",
11    name: "Home",
12    component: Home,
13  },
14  {
15    path: '/about',
16    name: "About",
17    component: About,
18  },
19  {
20    path: '/:catchAll(.*)*',
21    name: "PageNotFound",
22    component: PageNotFound,
23  },
24]
25...

保存并关闭文件。

此时此刻,你有三个不同的路线:

  • localhost:8080/,路由到 Home.vue
  • localhost:8080/about,路由到 About.vue
  • 任何其他路由,默认情况下路由到 PageNotFound.vue

一旦您保存了此文件,打开您的浏览器,并首先访问 localhost:8080/. 一旦应用程序加载,您将找到 Home.vue的内容:机场卡的收藏。

继续测试这些路线,访问localhost:8080/about,这是一个静态路线,所以你会找到About.vue组件的内容,该组件目前包含一个标题和一个段落。

A placehold about page for the sample app that reads "This is an about page"

接下来,您可以通过访问浏览器中的任何其他内容来测试PageNotFound.vue组件,例如,如果您访问localhost:8080/some-other-route,Vue Router 将默认使用该catchAll路线,因为该路线没有定义。

正如本步骤所示,Vue Router 是一个实用的第一方库,该库可返回与特定路线相关联的组件. 在此步骤中,该库通过main.js 文件在全球范围内下载并集成,并在您的src/router/index.js 文件中配置。

到目前为止,你的大部分路径都是 exact 路径,这意味着一个组件只会安装,如果URL片段完全匹配路由器的路径。然而,还有其他类型的路径有自己的目的,可以动态地生成内容。

步骤 4 – 使用参数创建路线

在此时,您已经创建了两个准确的路线和一个动态路线到一个 404页面,但Vue Router 拥有更多这些类型的路线,您可以在Vue Router 中使用以下路线:

  • 动态路径:具有动态参数的路径,您的应用程序可以引用来加载独特的数据。
  • 命名路径:可以使用名称属性访问的路径. 在此时创建的所有路径都有名称属性。
  • 嵌套路径:与其相关的儿童路径。
  • 静态或准确路径:具有静态路径值的路径。

在本节中,您将创建一个动态路线,显示单个机场信息和机场目的地的嵌套路线。

动态路线

例如,如果您想要创建一个视图以显示根据URL栏中的机场代码显示机场信息的视图,您可以使用一个动态路线。在本示例中,如果您要访问localhost:8080/airport/cvg的路线,您的应用程序将显示来自机场的数据,代码为cvg,即辛辛那提/北肯塔基国际机场。

打开终端并使用触摸命令创建一个新的.vue文件. 如果src是当前的工作目录,则命令将看起来像这样:

1touch views/AirportDetail.vue

创建后,请在您所选择的文本编辑器中打开此文件,然后继续创建您的模板脚本标签以设置此组件:

 1[label airport-codes/src/views/AirportDetail.vue]
 2<template>
 3  <div>
 4
 5  </div>
 6</template>
 7
 8<script>
 9export default {
10  setup() { }
11}
12</script>

保存并关闭此文件。

接下来,您需要将此视图注册到src/router/index.js文件中,然后在文本编辑器中打开此文件,然后添加以下突出的行:

 1[label airport-codes/src/router/index.js]
 2import Home from '@/views/Home.vue'
 3import About from '@/views/About.vue'
 4import AirportDetail from '@/views/AirportDetail.vue'
 5import PageNotFound from '@/views/PageNotFound.vue'
 6
 7...
 8const routes = [
 9  {
10    path: "/",
11    name: "Home",
12    component: Home,
13  },
14  {
15    path: '/about',
16    name: "About",
17    component: About,
18  },
19  {
20    path: '/airport/:code',
21    name: "AirportDetail",
22    component: AirportDetail,
23  },
24  {
25   path: '/:catchAll(.*)*',
26   name: "PageNotFound",
27   component: PageNotFound,
28  },
29]
30...

这个新路线中的 :代码 称为 parameter. 参数是您应用程序可以通过这个名称访问的任何值. 在这种情况下,您有一个名为 `code' 的参数。

保存并关闭此文件。

现在你有数据,请重新打开AirportDetail.vue组件,将机场数据导入到此组件中:

1[label airport-codes/src/views/AirportDetail.vue]
2...
3<script>
4import airports from '@/data/airports.js'
5
6export default {
7  setup() { }
8}
9</script>

接下来,创建一个计算属性,如果该对象的缩写属性匹配URL中的:代码参数,则该属性会返回数组中的一个对象。

 1[label airport-codes/src/views/AirportDetail.vue]
 2...
 3<script>
 4import { computed } from 'vue'
 5import { useRoute } from 'vue-router'
 6import airports from '@/data/airports.js'
 7
 8export default {
 9  setup() {
10  const route = useRoute()
11    const airport = computed(() => {
12    	return airports.filter(a => a.abbreviation === route.params.code.toUpperCase())[0]
13    })
14
15    return { airport }
16  }
17}
18</script>

此计算属性使用 JavaScript 中的 [filter array method](https://andsky.com/tech/tutorials/how-to-use-array-methods-in-javascript-iteration-methods#filter()来返回一个对象的数组,如果条件满足,因为您只需要一个对象,代码将始终返回第一个对象,它将使用 [0] 索引语法访问。 route.params.code 是您如何访问路由器文件中定义的参数。 为了访问路由器的属性,您需要从 vue-router 导入一个名为 useRoute 的函数。 现在,当您访问路由器时,您可以立即访问路由器的所有属性。

在此时,此计算属性将返回单个机场对象,如果URL中的代码匹配缩写属性,这意味着您可以访问机场的所有对象属性,并可以构建该组件的模板

继续在文本编辑器中编辑AirportDetail.vue文件,并构建您的模板以显示机场信息:

1[label airport-codes/src/views/AirportDetail.vue]
2<template>
3 <div>
4   <p>{{ airport.name }} ({{ airport.abbreviation }})</p>
5   <p>Located in {{ airport.city }}, {{ airport.state }}</p>
6 </div>
7</template>
8...

打开您的浏览器并访问localhost:8080/airport/sea。有关西雅图-塔科马国际机场的信息将在您的浏览器中显示,如下图像所示:

Informational page about the Seattle-Tacoma International Airport, including its abbreviation and location.

无线路

随着应用程序的增长,你可能会发现你有许多与父母相关的路径。一个很好的例子可能是与用户相关的路径系列。如果有一个名为foo的用户,你可能会为同一个用户有多个嵌套路径,每个路径都从/user/foo/开始。当用户处于/user/foo/profile路线时,用户会查看与他们相关的个人资料页面。用户的帖子页面可能有一个/user/foo/posts路线。

在本节中,您将添加一个视图以显示每个机场支持的目的地。

打开您的终端,并在src目录中创建一个名为AirportDestinations.vue的新文件:

1touch views/AirportDestinations.vue

接下来,打开文本编辑器并添加以下内容:

 1[label airport-codes/src/views/AirportDestinations.vue]
 2<template>
 3  <h1>Destinations for {{ airport.name }} ({{ airport.abbreviation }}</h1>
 4  <h2>Passenger</h2>
 5  <ul>
 6    <li v-for="(destination, i) in airport.destinations.passenger" :key="i">
 7      {{ destination }}
 8    </li>
 9  </ul>
10  <h2>Cargo</h2>
11  <ul>
12    <li v-for="(destination, i) in airport.destinations.cargo" :key="i">
13      {{ destination }}
14    </li>
15  </ul>
16</template>
17
18<script>
19  import { computed } from 'vue'
20  import { useRoute } from 'vue-router'
21  import airports from '@/data/airports.js'
22
23  export default {
24    setup() {
25      const route = useRoute()
26      const airport = computed(() => {
27        return airports.filter(a => a.abbreviation === route.params.code.toUpperCase())[0]
28      })
29    return { airport }
30  }
31}
32</script>

此视图将从airports.js文件中显示每个机场的所有目的地. 在此视图中,您正在使用v-for指令来迭代目的地。 类似于AirportDetail.vue视图,您正在创建一个名为airport的计算属性,以便在URL栏中找到匹配:code参数的机场。

保存并关闭文件。

要创建嵌套路线,您需要将孩子属性添加到src/router/index.js文件中的路线对象中。

打开router/index.js并添加以下突出的行:

 1[label airport-codes/src/router/index.js]
 2import Home from '@/views/Home.vue'
 3import About from '@/views/About.vue'
 4import AirportDetail from '@/views/AirportDetail.vue'
 5import AirportDestinations from '@/views/AirportDestinations.vue'
 6import PageNotFound from '@/views/PageNotFound.vue'
 7
 8...
 9const routes = [
10    ...
11  {
12    path: '/airport/:code',
13    name: "AirportDetail",
14    component: AirportDetail,
15    	children: [
16    		{
17    		  path: 'destinations',
18    			name: 'AirportDestinations',
19    			component: AirportDestinations
20    		}
21    	]
22  },
23    ...
24]
25...

这个孩子的路径与其父母相比是短的,这是因为,在嵌套的路径中,你不需要添加整个路径,孩子继承了父母的路径,并将其提前给孩子路径

打开浏览器窗口,然后访问localhost:8080/airport/msp/destinations。没有什么看起来与父母AirportDetails.vue不同,这是因为当你使用嵌套路线时,你需要在父母中包含<router-view />组件。当你访问孩子的路线时,Vue会将儿童视图中的内容注入父母:

1[label airport-codes/src/views/AirportDetail.vue]
2<template>
3 <div>
4   <p>{{ airport.name }} ({{ airport.abbreviation }})</p>
5   <p>Located in {{ airport.city }}, {{ airport.state }}</p>
6     <router-view />
7 </div>
8</template>

在这种情况下,在浏览器中访问目的地路线时,‘AirportDestinations.vue’将显示Minneapolis-Saint Paul国际机场支持的目的地列表,无论是乘客还是货物航班。

A page rendered with a list of passenger and cargo destinations for Minneapolis-Saint Paul International Airport.

在此步骤中,您创建了动态和嵌套路线,并学会了如何使用计算属性来检查URL栏中的 :代码'参数. 现在所有路线已经创建,在最后一步中,您将通过使用 ` 组件创建链接来导航不同类型的路线。

步骤5:在路线之间导航

当与单页应用程序工作时,你需要注意一些警告:由于每个页面都被引导到一个HTML页面,使用标准(<a />)导航内部路径之间不会起作用,而您需要使用Vue Router提供的`组件。

与标准的锁标签不同,路由器链接提供了许多不同的方法来链接到您的应用程序中的其他路径,包括使用命名路径。命名路径是与它们相关联的名称属性的路径。

当您最初将 Vue Router 集成到您的应用程序时,<router-link />组件在全球范围内被导入,要使用此组件,您将将其添加到您的模板中,并为其提供一个支持值。

在您的编辑器中的视图目录中打开Home.vue组件. 此视图显示了您在airports.js文件中的每个机场. 您可以使用路由器链接来替换包含div的标签,以便使每个卡片可点击到各自的详细视图。

在「Home.vue」中添加以下突出的行:

 1[label airport-codes/src/views/Home.vue]
 2<template>
 3    <div class="wrapper">
 4    	<router-link v-for="airport in airports" :key="airport.abbreviation" class="airport">
 5    		<p>{{ airport.abbreviation }}</p>
 6    		<p>{{ airport.name }}</p>
 7    		<p>{{ airport.city }}, {{ airport.state }}</p>
 8    	</router-link>
 9    </div>
10</template>
11...

在最低限度上,路由器链接需要一个叫做To的接口。这个To接口接受一个具有多个键/值对的对象。由于该卡使用v-for指令,这些卡是数据驱动的。您需要能够导航到AirportDetail.vue组件。如果您查看该组件的路径,则可以通过/airports/:code访问。

当您通过路径属性导航时,它是一对一匹配。

1[label airport-codes/src/views/Home.vue]
2<template>
3    <div class="wrapper">
4    	<router-link :to="{ path: `/airports/${airport.abbreviation}` }" v-for="airport in airports" :key="airport.abbreviation" class="airport">
5    		...
6    	</router-link>
7    </div>
8</template>
9...

在此代码中,您正在使用 JavaScript string interpolation以动态地插入机场代码作为路径属性的值。然而,随着应用程序的规模增长,您可能会发现通过路径导航到不同的路径不是最佳方法。

要实现命名路线,请在路径上使用路线的名称。 如果您引用src/router/index.js,则会发现AirportDetail.vueAirportDetail的名称:

1[label airport-codes/src/views/Home.vue]
2<template>
3    <div class="wrapper">
4    	<router-link :to="{ name: 'AirportDetail' }" v-for="airport in airports" :key="airport.abbreviation" class="airport">
5    		...
6    	</router-link>
7    </div>
8</template>
9...

使用命名路线的优势在于,命名路线不取决于路线的路径

如果您需要将参数传入命名路线,您将需要添加包含代表参数的对象的参数属性:

1[label airport-codes/src/views/Home.vue]
2<template>
3    <div class="wrapper">
4    	<router-link :to="{ name: 'AirportDetail', params: { code: airport.abbreviation } }" v-for="airport in airports" :key="airport.abbreviation" class="airport">
5    		...
6    	</router-link>
7    </div>
8</template>
9...

保存此文件并在您的浏览器中查看它在localhost:8080。点击西雅图 - 塔科马机场地图将现在导航到localhost:8080/airport/sea

编程导航

当您需要在 HTML 模板中导航到另一个视图时,您可以使用<router-link />组件,但是当您需要在 JavaScript 函数中导航路径之间时,您需要如何解决这个问题?Vue Router 提供了一个名为 programmatic navigation 的解决方案。

在本教程中早些时候,您创建了一条名为PageNotFound的捕捉路线,如果机场计算属性在AirportDetail.vueAirportDestinations.vue组件中返回未定义时,将始终导航到该页面将是一个很好的用户体验。

在文本编辑器中,打开AirportDetail.vue组件。 要做到这一点,请检测airport.value是否未定义。 此函数将在组件首次安装时被调用,这意味着您需要使用Vue的生命周期方法。

添加以下突出的线条:

 1[label airport-codes/src/views/AirportDetail.vue]
 2<template>
 3  <div v-if="airport">
 4   <p>{{ airport.name }} ({{ airport.abbreviation }})</p>
 5   <p>Located in {{ airport.city }}, {{ airport.state }}</p>
 6   <router-view />
 7  </div>
 8</template>
 9
10<script>
11    import { computed, onMounted } from 'vue'
12    import { useRoute } from 'vue-router'
13    import airports from '@/data/airports.js'
14    import router from '@/router'
15
16    export default {
17    		setup() {
18        const route = useRoute()
19    			const airport = computed(() => {
20    				return airports.filter(a => a.abbreviation === route.params.code.toUpperCase())[0]
21    			})
22    				
23    			onMounted(() => {
24    				if (!airport.value) {
25    					// Navigate to 404 page here
26    				}
27    			})
28    				
29    			return { airport }
30    		}
31    }
32</script>

在这个onMounted函数中,你正在检查airport.value是否是一个错误的值。如果是,那么你将路由到PageNotFound。你可以处理编程路由,就像你处理了路由器链接组件一样。由于你不能在JavaScript函数中使用组件,你需要使用router.push({... })

 1[label /src/views/AirportDetail.vue]
 2<script>
 3    ...
 4  onMounted(() => {
 5    	if (!airport.value) {
 6    		router.push({ name: 'PageNotFound' })
 7    	}
 8  })
 9    ...
10</script>

如果路线不存在,或者数据不正确返回,这将保护用户免受网页破坏。

保存文件并导航到localhost:8080/airport/ms。由于ms不是数据中的机场代码,所以airport对象将未定义,路由器将重定向您到 404页面。

结论

在本教程中,您使用Vue Router创建了一个在不同视图之间路由的Web应用程序,您了解了不同的路由类型,包括准确的,命名和嵌套,以及使用路由器链接组件创建了参数链接。

有关 Vue Router的更多信息,建议您阅读他们的文档。 CLI 工具特别具有许多本教程未涵盖的附加功能。

Published At
Categories with 技术
comments powered by Disqus