现代单页 Web 应用程序 (SPA) 最强大的功能之一是路由。现代单页应用程序(例如 Vue 应用程序)可以在客户端从一个页面转换到另一个页面(无需请求服务器)。Vue Router是 Vue 应用中页面导航的官方库。Vue Router 使用简单,但功能强大。在本文中,我们将深入探讨Vue Router 4(与 Vue 3 一起使用)。我们将介绍您需要了解的所有内容,以舒适地使用 Vue Router。
我们将涵盖:
- Vue 路由器基础知识
- 动态路由
- 如何传递路由器参数
- 延迟加载
无论您是刚接触 Vue Router 的初学者,还是希望提高技能的经验丰富的 JavaScript/Vue 开发人员,本教程都能为您提供一些帮助。让我们开始吧。
我们还创建了一个完全免费的深度Vue Router 视频课程。如果您通过观看视频学习得更好,我们强烈建议您试一试。单击此处观看 Vue 路由器课程。
Vue 路由器基础知识
让我们创建一个新项目并开始编码。我们将使用vue-cli创建一个新项目。如果你没有安装它,你可以通过运行来安装它npm install -g @vue/cli
。
# Create a new Vue project
vue create myapp
cd myapp
# start your app by running the following command
npm run serve
接下来,我们可以通过运行以下命令将 Vue Router 添加到我们的项目中。
vue add router
将cli
询问我们是否想要历史模式。对于本教程,我们将使用历史模式,因此我们将选择是。
让我们看一下为我们创建的文件夹结构。
为我们创建了一个名为的文件夹views
以及两个文件About.vue
和Home.vue
. 这些文件代表我们的页面。router/index.js
还会生成一个名为file 的文件。此文件包含所有路由器配置。让我们打开router/index.js
文件。
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
我们正在从库中导入createRouter
和导入。接下来,我们从. 在第 3 行,我们声明了一个名为路由的对象数组。这个数组代表我们在应用程序中的路由。这些数组项称为路由对象。第一个路由对象有一个路径,这意味着这将是我们的基本 URL。component 属性表示当用户访问该路径时将呈现什么组件。我们将在此路径上呈现主页。最后,name 属性表示路由的名称。createWebHistory
vue-router
views/Home.vue
/
/about
对于路径,我们几乎遵循相同的逻辑。但是,我们不是直接导入组件,而是通过 Webpack 的代码拆分功能来导入它。稍后再谈。
现在让我们进入App.vue
文件。
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view/>
</template>
<style>
</style>
观察router-link
标签。这些标签只是花哨的锚链接。然而,与锚链接(<a href="">
标签)不同,它<router-link>
不会重新加载整个页面。请记住 Vue 是一个单页应用程序。该应用程序的数据已从服务器下载。当我们路由到另一个视图时,应用程序只是隐藏一些信息并显示请求的信息。router-link
标签有一个to
属性,它指的是访问哪个页面。<router-view/>
标签是在触发导航链接时呈现正确组件的内容。
让我们向这个应用程序添加我们自己的路由。
// App.vue
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
<router-link to="/profile">Profile</router-link>
</div>
<router-view/>
</template>
我们需要添加一个新的路由器链接到App.vue
. 接下来,我们在views 目录中创建一个新组件。
// views/Profile.vue
<template>
<div class="home">
Profile Info
</div>
</template>
最后,在我们的 routes 数组中,我们必须导入它并指定路由路径。
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import Profile from '../views/Profile.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/profile',
name: 'profile',
component: Profile,
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
就是这样,我们将自己的路由添加到应用程序中。
如何在 Vue 路由器中使用路由器参数
首先,我们来看看什么是路由器参数(简称router params),以及为什么它们很重要。假设我们的应用程序中有一个页面,我们向用户显示所有可用博客文章的列表。
假设在我们的应用程序中这条路径是/posts
. 当用户点击任何这些文章时,用户将被带到该文章页面。对于每篇文章,路径会有所不同(/posts/article-1
、/posts/article-2
等)。我们如何实现这一目标?我们可以为每个帖子添加一条新路由,但是每次发布新帖子时我们都必须更改我们的代码。因此,我们将使用动态路由。这是路由器参数派上用场的地方。
在我们的应用程序中,我们可以指定一个通用路由,比如/posts
and,然后我们可以指定可选的路由参数到相同的路由,比如 this /posts/:id
。:id
拾取任何动态字符串作为参数。这意味着我们现在可以路由到 、 等路径/posts/article-1
,/posts/article-2
并且应用程序中的 Vue 路由器将知道我们试图去哪条路径。
让我们在我们的应用程序中看到这一点。
// App.vue
<template>
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link :to="{ name: 'profile', params: { username: 'mark2021' } }" >
Profile
</router-link>
</div>
<router-view/>
</template>
在我们的router-link
标签中,我们可以使用该:to
属性来传递一个带有名称和参数数据的对象。params 对象可以是任何类型的数据(即字符串、数字、对象)。在上面的代码片段中,我们传入了一个username
带有字符串值(mark2021)的对象。
如何从视图访问路由参数
当我们将 Vue 路由器添加到 Vue 应用程序时,我们可以访问应用$route
程序全局范围内的特殊对象。该对象包含我们应用程序的所有路由器信息。我们可以$route
通过简单地调用来访问对象this.$route
。参数信息也在此$route
对象中可用。我们可以通过对象访问params
Profile 组件内部的$route
对象。看看下面的代码片段。
<template>
<div class="profile">
Profile Info
</div>
<span>
{{ this.$route.params.username }}
</span>
</template>
动态路由
下面是一个快速参考表,可帮助您直观地了解动态路由的工作原理。
路线模式 | 网址路径 | $this.route.params |
---|---|---|
/产品名称 | /产品/苹果手表 | { name: "apple-watch"} |
/product/:name/comment/:comment_id | /产品/苹果手表/评论/123 | { name: 'apple-watch', comment_id: '123' } |
在上一节中,我们看到了如何使用<router-link>
. 动态路由是一个类似的概念。在这种情况下,参数是其URL
自身的一部分。
让我们看看如何在应用程序中定义动态路由。让我们在 view 下创建一个新组件并调用它Product
。
<template>
<div>
Product Page
</div>
<span>
Looking for Product: {{ this.$route.params.id }}
</span>
</template>
现在我们可以将此组件添加到我们的路由中。
const routes = [
// rest of the code ...
{ path: '/product/:id', component: Product },
]
:id
请注意,我们在 URL 中附加了一个动态参数。现在,如果您http://localhost:8080/product/12343
在我们的浏览器中访问,您可以看到该组件将可以访问通过 URL 传递的动态参数。
然后,我们可以使用它Id
在生命周期挂钩中从我们的 API 获取实际产品。
我们还可以在 URL 中包含多个动态参数。动态段将映射到 的相应字段$route.params
。
让我们来看看它是如何工作的。我们将首先对我们的产品路线进行一些快速更改。
const routes = [
// rest of the code ...
{ path: '/product/:id/:category', component: () => import('../views/Product.vue') }
]
:id
现在我们指定两个参数,而不是一个参数。现在让我们继续前进http://localhost:8080/product/12343/electronics
并打开 Vue 开发工具。正如您从下面的屏幕截图中看到的那样,我们现在可以访问参数,这些参数映射到指定的变量名称id
和category
.
延迟加载
让我们谈谈延迟加载。这是 Vue Router 开箱即用的高级功能之一。让我们打开我们的开发工具并观察js
选项卡。
您可以看到,当我们第一次加载应用程序时,它会加载一个app.js
脚本。当您导航到/profile
route 或/product
route 时,您可以看到没有新的 javascript 正在加载。这是因为这些组件的所有 JavaScript 代码都已经加载了app.js
. 在较小的应用程序中,这不是问题。但是,如果我们有一个大型应用程序怎么办。在这种情况下,一次性加载所有 JS 代码可以显着延长页面加载时间。延迟加载用于避免这种情况。
当我们延迟加载时,我们只在需要时加载我们需要的部分。
// router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/profile',
name: 'profile',
component: Profile,
},
{ path: '/product/:id', component: Product },
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
看看第 17 行router/index.js
。你还记得前面的例子吗?这里的About
组件是用箭头函数导入的。这是延迟加载的示例。和组件不同的是Home
,组件没有加载。只有当用户访问该路由时,该组件才会被加载。这就是我们实现延迟加载所要做的一切。这种延迟加载是通过 Webpack 的代码拆分功能完成的。在幕后,Vue 使用 Webpack 作为打包器。您可以在我们的Vue 3 Masterclass课程中深入了解高级 Vue 功能,例如代码拆分、Webpack 配置等。Profile
Product
About
app.js
About
/about
我们可以更新我们的代码以对每个路由使用延迟加载。
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/profile',
name: 'profile',
component: () => import('../views/Profile.vue')
},
{ path: '/product/:id', component: () => import('../views/Product.vue') },
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
如果您希望通过对 Vue 的深入了解而使自己与众不同,那么请试试我们的Vue 3 Masterclass。在本课程中,我们深入探讨了 Vue 的一些高级特性,例如高阶函数、代码拆分、Webpack 配置、创建 vue 插件、路由保护等等。
程序化导航
在我们的应用程序中,会出现我们希望以编程方式导航到另一个页面的场景。在我们的应用程序中,我们可以访问路由器实例$router
。我们可以通过调用来访问它**this.$router**
。路由器实例有一个叫做 push 的函数。此功能可用于导航到不同的路线。以下是它如何工作的一些示例
// route by route path
this.$router.push('home')
// object
this.$router.push({ path: 'home' })
// named route navigation with parameters
this.$router.push({ name: 'user', params: { userId: '123' } })
// with query params, resulting in /profile?info=some-info
this.$router.push({ path: 'profile', query: { info: 'some-info' } })
从这往哪儿走
我希望这篇文章能让你大致了解 Vue Router 的不同功能。我们讨论了 Vue Router 最重要和最常用的特性。随意访问vue 路由器文档以获取有关各种 API 的更深入的详细信息。