Vue 路由器初学者指南
Posted 光吃不胖的可爱酱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vue 路由器初学者指南相关的知识,希望对你有一定的参考价值。
我们将研究如何使用 Vue Router 在 Vue 应用程序中实现路由。所以我们可以进行动手实践,我们将使用 Vue 和 Vue Router 构建一个简单的 Pokedex 应用程序。
具体来说,我们将介绍以下内容:
- 设置路由器
- 路由参数
- 声明式和程序化导航
- 嵌套路由
- 404 页
每个允许创建单页应用程序的 javascript UI 框架都需要一种将用户从一个页面导航到另一个页面的方法。所有这些都需要在客户端通过将当前显示在页面上的视图与地址栏中的 URL 同步来进行管理。在 Vue 世界中,管理此类任务的 [官方库] 是 Vue Router。
与以往一样,本教程的代码可以在GitHub上找到。
先决条件
以下是必需的,以便您可以充分利用本教程:
- html、CSS、JavaScript 和 Vue 的基本知识。如果您知道如何使用 Vue 在页面上呈现某些内容,那么您应该能够跟进。对 API 有一点了解也会有所帮助。
- 您的机器上安装了Node.js和Vue CLI 。我们将在本教程中使用 Vue 3,因此请确保更新 Vue CLI。
应用概览
我们将构建一个 Pokedex 应用程序。它将包含三个页面:
- 口袋妖怪列表页面。这是列出所有原始 151 口袋妖怪的默认页面。
- 口袋妖怪页面。这是我们显示基本细节的地方,例如类型和描述。
- 口袋妖怪详细信息页面。这是我们展示进化链、能力和动作的地方。
设置应用程序
使用 Vue CLI 启动一个新的 Vue 应用程序:
vue create poke-vue-router
从列出的选项中选择 Vue 3:
完成后,在项目文件夹中导航并安装我们需要的库:
cd poke-vue-router
npm install vue-router@4 axios
请注意,我们使用的是 Vue Router 4 而不是 3,这是您使用 Google 搜索时显示的默认结果。它是在next.router.vuejs.org
而不是router.vuejs.org
。我们正在使用 Axios 向PokeAPI v2发出请求。
此时,最好运行项目以确保默认的 Vue 应用程序正常工作:
npm run serve
访问http://localhost:8080/
您的浏览器并检查默认的 Vue 应用程序是否正在运行。它应该显示如下内容:
接下来,您需要添加sass-loader
作为开发依赖项。出于本教程的目的,最好只安装我使用的相同版本。这是因为,在撰写本文时,最新版本与 Vue 3 不兼容:
npm install sass-loader@10.1.1 --save-dev
node-sass
出于与上述相同的原因,您还需要安装。最好坚持使用与我相同的版本:
npm install node-sass@4.14.1 --save
注意:如果以这种方式安装 Sass 对您不起作用,您还可以在使用 CLI 创建 Vue 应用程序时选择手动选择功能。然后,选择CSS Preprocessors并选择Sass/SCSS (with dart-sass)。
创建应用程序
现在我们准备开始构建应用程序。在您继续操作时,请记住根目录是src
文件夹。
从更新main.js
文件开始。这是我们导入根组件App.vue
和router/index.js
声明与路由相关的所有内容的文件的地方:
// main.js
import createApp from "vue";
import App from "./App.vue";
import router from "./router";
const app = createApp(App);
app.use(router);
app.mount("#app");
设置路由器
在App.vue
文件中,使用router-view
Vue Router 提供的组件。这是 Vue Router 使用的最顶层组件,它为用户访问的当前路径呈现相应的组件:
// App.vue
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
export default
name: "App",
;
</script>
接下来,创建一个新router/index.js
文件并添加以下内容。要创建路由器,我们需要从 Vue Router中提取createRouter
和。允许我们创建一个新的路由器实例,同时创建一个 HTML5 历史记录,它基本上是History API的包装器。当我们在页面之间导航时,它允许 Vue Router 操作地址栏中的地址:createWebHistory
createRouter
createWebHistory
// router/index.js
import createRouter, createWebHistory from "vue-router";
在此之下,导入我们将使用的所有页面:
import PokemonList from "../views/PokemonList.vue";
path
Vue Router 需要一个包含, name
, 和component
作为其属性的对象数组:
-
path
: 这是你想要匹配的模式。在下面的代码中,我们正在匹配根路径。因此,如果用户尝试访问http://localhost:8000
,则匹配此模式。 -
name
:页面的名称。这是页面的唯一标识符,当您想从其他页面导航到此页面时,您将使用该标识符。 -
component
path
:当与用户访问的 URL 匹配时要呈现的组件。
const routes = [
path: "/",
name: "PokemonList",
component: PokemonList,
,
];
最后,通过提供一个包含 thehistory
和routes
to的对象来创建路由器实例createRouter
:
const router = createRouter(
history: createWebHistory(),
routes,
);
export default router;
这就是我们现在所需要的。您可能想知道其他页面在哪里。我们将在稍后添加它们。现在,让我们先在默认页面上工作。
创建页面
创建页面实际上并不需要任何特殊代码。所以如果你知道如何在 Vue 中创建自定义组件,你应该能够创建一个页面供 Vue Router 使用。
创建一个views/PokemonList.vue
文件并添加下面的代码。在此文件中,我们使用自定义List
组件来呈现 Pokemon 列表。我们真正需要做的唯一一件事就是提供数据供List
组件使用。安装组件后,我们向 PokeAPI 发出请求。我们不希望列表变得太大,因此我们将结果限制在最初的 151 个 Pokemon。一旦我们得到结果,我们只需将其分配给组件的items
数据。这将反过来更新List
组件:
<template>
<List :items="items" />
</template>
<script>
import axios from "axios";
import List from "../components/List.vue";
export default
name: "PokemonList",
data()
return
items: null,
;
,
mounted()
axios.get(`https://pokeapi.co/api/v2/pokemon?limit=151`).then((res) =>
if (res.data && res.data.results)
this.items = res.data.results;
);
,
components:
List,
,
;
</script>
这是List
组件的代码。组件存储在components
目录中,因此创建一个components/List.vue
文件并添加以下内容:
<template>
<div v-if="items">
<router-link
:to=" name: Pokemon, params: name: row.name "
class="link"
v-for="row in items"
:key="row.name"
>
<div class="list-item">
row.name
</div>
</router-link>
</div>
</template>
<script>
export default
name: "List",
props:
items:
type: Array,
,
,
;
</script>
<style lang="scss" scoped>
@import "../styles/list.scss";
</style>
您可以在GitHub存储库中查看该styles/list.scss
文件的代码。
此时,您现在可以在浏览器中查看更改。除非您收到以下错误:
这是因为 Vue 正在尝试生成到 Pokemon 页面的链接,但还没有。Vue CLI 足够聪明,可以警告你。您可以使用 a<div>
代替components/List.vue
文件模板来临时解决此问题:
<template>
<div v-if="items">
<div v-for="row in items" :key="row.name"> row.name </div>
</div>
</template>
这样,您应该能够看到口袋妖怪的列表。添加 Pokemon 页面后,请记住稍后将其更改回来。
声明式导航
使用 Vue Router,您可以通过两种方式导航:声明式和编程式。声明式导航与我们在 HTML 中使用锚标记所做的几乎相同。您只需声明您希望链接导航到的位置。另一方面,编程导航是通过显式调用 Vue Router 来完成的,以在执行用户操作(例如单击按钮按钮)时导航到特定页面。
让我们快速分解它是如何工作的。要导航,您需要使用该router-link
组件。这需要的唯一属性是:to
. 这是一个包含name
要导航到的页面的对象,以及params
用于指定要传递给页面的参数的可选对象。在这种情况下,我们传入 Pokemon 的名称:
<router-link
:to=" name: Pokemon, params: name: row.name "
class="link"
v-for="row in items"
:key="row.name"
>
<div class="list-item">
row.name
</div>
</router-link>
要可视化其工作原理,您需要了解Pokemon
屏幕使用的模式。这是它的样子/pokemon/:name
::name
表示name
您传入的参数。例如,如果用户想查看皮卡丘,则 URL 将如下所示http://localhost:8000/pokemon/pikachu
。我们稍后会更详细地讨论这个问题。
路由参数
我们已经看到了如何为我们的路线匹配特定的模式,但我们还没有完成如何传入自定义参数。我们已经通过router-link
前面的示例简要地看到了它。
我们将使用下一页 ( Pokemon
) 来说明路由参数在 Vue Router 中是如何工作的。为此,您只需在参数名称前加上冒号 ( :
)。在下面的例子中,我们想传入 Pokemon 的名字,所以我们添加了:name
. 这意味着如果我们想导航到这个特定的路线,我们需要为这个参数传入一个值。正如我们在router-link
前面的示例中看到的,这是我们传递口袋妖怪名称的地方:
// router/index.js
import PokemonList from "../views/PokemonList.vue";
import Pokemon from "../views/Pokemon"; // add this
const routes = [
path: "/",
name: "PokemonList",
component: PokemonList,
,
// add this:
path: "/pokemon/:name",
name: "Pokemon",
component: Pokemon,
]
这是Pokemon
页面 ( views/Pokemon.vue
) 的代码。就像之前的 PokemonList 页面一样,我们将渲染 UI 的任务委托给一个单独的组件BasicDetails
。当组件被挂载时,我们向 API 的/pokemon
端点发出请求。要获取作为路由参数传入的口袋妖怪名称,我们使用this.$route.params.name
. 我们正在访问的属性应该与您在router/index.js
文件中为参数指定的名称相同。在这种情况下,它是name
. 如果您用于替代,您可以使用以下方式访问/pokemon/:pokemon_name
它:path
this.$route.params.pokemon_name
<template>
<BasicDetails :pokemon="pokemon" />
</template>
<script>
import axios from "axios";
import BasicDetails from "../components/BasicDetails.vue";
export default
name: "Pokemon",
data()
return
pokemon: null,
;
,
mounted()
const pokemon_name = this.$route.params.name;
axios
.get(`https://pokeapi.co/api/v2/pokemon/$pokemon_name`)
.then((res) =>
const data = res.data;
axios
.get(`https://pokeapi.co/api/v2/pokemon-species/$pokemon_name`)
.then((res) =>
Object.assign(data,
description: res.data.flavor_text_entries[0].flavor_text,
specie_id: res.data.evolution_chain.url.split("/")[6],
);
this.pokemon = data;
);
);
,
components:
BasicDetails,
,
;
</script>
以下是BasicDetails
组件 ( components/BasicDetails.vue
) 的代码:
<template>
<div v-if="pokemon">
<img :src="pokemon.sprites.front_default" : />
<h1> pokemon.name </h1>
<div class="types">
<div
class="type-box"
v-for="row in pokemon.types"
:key="row.slot"
v-bind:class="row.type.name.toLowerCase()"
>
row.type.name
</div>
</div>
<div class="description">
pokemon.description
</div>
<a @click="moreDetails" class="link">More Details</a>
</div>
</template>
<script>
export default
name: "BasicDetails",
props:
pokemon:
type: Object,
,
,
methods:
moreDetails()
this.$router.push(
name: "PokemonDetails",
params:
name: this.pokemon.name,
specie_id: this.pokemon.specie_id,
,
);
,
,
;
</script>
<style lang="scss" scoped>
@import "../styles/types.scss";
@import "../styles/pokemon.scss";
</style>
您可以在GitHub存储库中查看styles/types.scss
andstyles/pokemon.scss
文件的代码。
此时,您应该能够再次在浏览器中看到更改。您还可以将components/List.vue
文件更新回其原始代码,router-link
而不是<div>
.
程序化导航
您可能已经注意到我们在BasicDetails
组件中做了一些不同的事情。我们并没有真正导航到PokemonDetails
使用router-link
. 相反,我们使用了一个锚元素并拦截了它的点击事件。这就是程序化导航的实现方式。我们可以通过 访问路由器this.$router
。然后我们调用该push()
方法在历史堆栈顶部推送一个新页面。路由器将显示顶部的任何页面。当用户单击浏览器的后退按钮时,此方法允许导航回上一页,因为单击它只是将当前页面“弹出”到历史堆栈顶部。这个方法接受一个包含name
和params
属性的对象,所以它和你传递给to
中的财产router-link
:
methods:
moreDetails()
this.$router.push(
name: "PokemonDetails",
params:
name: this.pokemon.name,
specie_id: this.pokemon.specie_id,
,
);
,
,
嵌套路由
接下来,更新路由器文件以包含 Pokemon 详细信息页面的路径。在这里,我们使用嵌套路由来传递多个自定义参数。在这种情况下,我们传入name
and specie_id
:
import Pokemon from "../views/Pokemon";
import PokemonDetails JS周刊#406 - prototype 指南,Vue 3.0 开发计划,Create React App 2.0 发布终于等到你了,预售《Vue.js权威指南》签名版限量 100 本