Vue
【vue3】router路由
12-23 20:59本文目录
1、路由概念与原理
1.1 什么是路由
路由(英:router)就是对应关系。路由分为两大类:
① 后端路由
② 前端路由
本文所述的路由为前端路由。
1.2 SPA与前端路由
SPA指的是一个web网站只有唯一的一个HTML页面,所有组件的展示与切换都在这唯一的一个页面内完成。此时,不同组件之间的切换需要通过前端路由来实现。
重点:在SPA项目中,不同功能之间的切换,要依赖于前端路由来完成。
1.3 什么是前端路由
通俗易懂的概念:Hash地址与组件之间的对应关系。
1.4 前端路由的工作方式

2、路由体验:实现简易的前端路由(手动路由)
通过传统的 <a> 标签以及在 created 生命周期函数中监听 url 的变化,手动设置要显示的组件,此种用法仅作为入门案例展示,体验路由实现基本原理,实际应用极少,冗余较差。
① 定义路由组件:在 RouterMain.vue 中,导入 MyMai.vue、AboutMain.vue、ListMain.vue 三个组件,通过 data() 设置变量 comName,变量的值是要展示的组件名称

② 动态绑定组件名称:
⑴ 在 RouterMain.vue 的 <template> 标签中,声明3个 <a> 链接, 可通过点击不同的 <a> 链接,切换浏览器地址栏中的 Hash 值;
⑵ 再添加一个动态组件的 <components> 标签,通过 <components> 标签的 is 属性,动态切换要显示的组件。

③ 监听地址变化并切换组件:在 RouterMain.vue 的 created 生命周期函数中,监听浏览器地址栏中hash地址的变化

④ 以上设置的(手动路由)完整代码:
<template>
<h2>手动路由</h2>
<a href="#about">关于</a>
<a href="#my">我的</a>
<a href="#list">列表</a>
<!-- 绑定组件名称 -->
<component :is="comName"></component>
</template>
<script>
import MyMain from './MyMain.vue';
import AboutMain from './AboutMain.vue';
import ListMain from './ListMain.vue';
export default {
components: {
MyMain,
AboutMain,
ListMain
},
data() {
return {
comName: "AboutMain", //要展示的组件的名称
}
},
created() {
//监听url,发生变化时触发,更换组件
window.onhashchange = () => {
switch (location.hash) {
case '#my':
this.comName = 'MyMain';
break;
case '#about':
this.comName = 'AboutMain';
break;
case '#list':
this.comName = 'ListMain';
break;
}
}
}
}
</script>
提示:上面的案例仅用作体验,熟悉路由的工作原理,实际应用中并不会这样做。
3、vue-router 的基本用法
3.1 什么是 vue-router
vue-router 是 vue.js 官方给出的路由解决方案。它只能结合 vue 项目进行使用,能够轻松的管理 SPA 项目中组件的切换。
3.2 vue-router 的版本
vue-router 目前有 3.x 的版本和 4.x 的版本,其中:
vue-router 3.x 只能结合 vue2 进行使用,官方文档地址:https://router.vuejs.org/zh/
vue-router 4.x 只能结合 vue3 进行使用,官方文档地址:https://next.router.vuejs.org/zh/
3.3 vue-router 4.x 的基本使用步骤
① 在项目中安装 vue-router
② 定义路由组件
③ 声明路由链接和占位符
④ 创建路由模块
⑤ 导入并挂载路由模块
3.4 在项目中安装 vue-router
在vue3的项目中,只能安装并使用 vue-router 4.x ,安装命令如下:
npm install vue-router@next -S
安装过程:

3.5 在项目中创建组件,声明路由链接和占位符
① 创建组件:在项目中定义 MainMy.vue、MainAbout.vue、MainList.vue 三个组件,后面将使用 vue-router 控制他们的展示与切换

② 声明路由链接和占位符:router-link 和 router-view 是 vue 提供的两个组件,使用 <router-link> 标签来声明路由链接,使用 <router-view> 标签来声明路由占位符

3.6 创建路由模块
① 在 src 目录中创建 router.js 路由模块

② 编辑 router.js 文件,从 vue-router 中按需导入 createRouter 和 createWebHashHistory 两个方法,并做如下配置:

3.7 导入并挂载路由模块
编辑 main.js 文件,导入并挂载上面定义的 router 路由模块

4、vue-router 的高级用法
4.1 路由重定向
路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C,从而展示特定的组件页面。
实现方法:通过路由规则的 redirect 属性,指定一个新的路由地址,可以方便快捷的设置路由重定向。
打开 router.js 文件,在 router 实例对象中添加如下配置:

4.2 路由高亮
vue 的 router 可以通过如下两种方式,将激活的路由链接进行高亮显示:
① 使用默认的高亮 class 类
被激活的路由链接,默认会添加一个叫做 router-link-active 的类名,可以使用此类名选择器,为激活的路由链接设置高亮样式。

② 自定义路由高亮的 class 类
在创建路由的实例对象时,开发者可以基于 linkActiveClass 属性,自定义路由链接被激活时所应用的类名,打开路由模块 router.js 文件,添加以下配置:

打开浏览器可以看到激活的路由链接 class 已变成自定义的名称

③ 动态路由匹配时的高亮
如果在路由配置中加了对参数的匹配,上面这种简单的路由配置会导致路由高亮失效,比如 path: '/list/:id',这时访问 /list 时不论是否携带id,可能都不会添加高亮的 class,解决方法有多种,下面简单提一下:
第一是在 router.js 路由模块中加上:
meta: { activeMenu: '/list' }
在组件对应的 router-link 标签加上:
:class="{ 'active': $route.meta.activeMenu === '/list' }"
这种做法缺点是:需要对每个路由链接都加上相应的配置,代码冗余多,可维护性差,增加了不必要的复杂度


第二种比较推荐,在组件中声明路由链接时,加上:
:class="{ 'active': $route.path.startsWith('/list') }"

4.3 嵌套路由
比如在一个组件中,嵌套其它的组件,并且可以通过按钮对组件进行切换,这种通过路由实现组件的嵌套展示,叫做嵌套路由,实现方法如下:
① 声明子路由链接和子路由占位符:在子组件 MainAbout.vue 中,声明 tab1 和 tab2 的子路由链接以及子路由占位符(tab1 和 tab2 分被对应已经创建好的组件)

② 在 router.js 路由模块中,导入需要的组件,并使用 children 属性声明子路由规则

③ 在嵌套路由中使用路由重定向:默认情况下,不会展示某个被嵌套的子路由(对应的组件),当希望打开某个页面时,能立即显示某个被嵌套的子组件,这时需要在嵌套路由中使用路由重定向(在路由规则中添加redirect属性)

4.4 动态路由匹配
动态路由指的是:把 Hash 地址中可变的部分定义为参数项,从而提高路由规则的复用性。通俗的说,就是在路由中设置要匹配的参数,比如:id、page、pagesize 等。
在 vue-router 中使用英文的冒号“:”来定义路由的参数项, 比如:
//路由中的动态参数以 : 进行声明,冒号后面的是动态参数的名称
{ path: '/list/:id', component: MainList }
//等同于将下面的路由规则,合并成一个,提高复用性
{ path: '/list/1', component: MainList}
{ path: '/list/2', component: MainList}
{ path: '/list/3', component: MainList}
下面通过实际案例演示设置与接收动态路由
① 在 router.js 路由模块中设置动态路由规则

② 在通过动态路由匹配方式渲染出来的组件中,可以使用 $route.params 对象访问到动态匹配的参数值
注意:$route.params 对象可在任意组件中(子组件、根组件等)使用,并不局限于路由指定的组件

③ 使用 props 接收路由参数:为了简化路由参数的获取形式,vue-router 允许在路由规则中开启 props 传参,具体操作如下:
编辑 router.js 路由模块,在对应的路由规则后面添加 props: true 参数项

在本条路由对应的组件中,使用 props 接收路由参数(仅限于路由对应的组件中,父组件、根组件等都不可用)

4.5 编程式导航
① vue-router 中的编程式导航 API
通过调用 API 实现导航的方式,叫做编程式调行。与之对应的,通过点击链接实现导航的方式,叫做声明式导航。比如:
- 普通网页中点击 <a> 链接、vue 项目中点击 <router-link> 都属于声明式导航
- 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
vue-router 提供了许多编程式导航的 API,其中最常用的两个 API 分别是:
this.$router.push('hash地址') //跳转到指定 Hash 地址,从而展示对应的组件
this.$router.go('数值n') //实现导航历史的前进、后退
② 调用 $router.push() 方法,可以跳转到指定的 hash 地址,从而展示对应的组件页面。

③ 调用 $router.go() 方法,可以在浏览历史中进行前进和后退

4.6 命名路由
在router.js路由模块定义路由规则时,通过 name 属性为路由规则定义名称的方式,叫做命名路由。
① 定义命名路由:打开 router.js 路由模块,在路由规则中添加 name 属性,注意:命名路由的 name 值不能重复,必须保证唯一性。

② 使用命名路由实现声明式导航:为 <router-link> 标签动态绑定 to 属性的值,并通过 name 属性指定要跳转到的路由规则。还可以增加 params 属性指定要携带的路由参数:

③ 调用 push 函数,传入一个配置对象,name 是要跳转到的路由规则,params 是携带的路由参数:

注意:即使用了路由命名的 name 属性,实际渲染依然是路由模块中 path 对应的值

④ 命名路由使用场景
命名路由在hash地址比较短时,体现不出优势,在hash地址比较长时,直接提供name名称比提供hash值要方便很多。
4.7 导航守卫
① 导航守卫可以控制路由的访问权限,示意图如下:


② 声明导航守卫:全局导航守卫会拦截每个路由规则,从而对每个路由进行访问权限的控制。打开 router.js 路由模块,添加 router.beforeEach 方法就可以声明一个全局的导航守卫,如下所示

③ 守卫方法的参数:全局导航守卫的守卫方法可以接收 3 个形参(可选),分别是:
- to 表示目标路由对象
- from 表示当前导航正要离开的路由对象
- next 是一个函数,表示放行规则

上面可以打印出两个对象和一个方法:

④ 在守卫方法中 next 函数的注意事项:
⑴ 不声明 next 形参,默认允许用户访问每一个路由

⑵ 声明了 next 形参但没调用,不允许用户访问任何一个路由

⑶ 声明了 next 形参并且调用,允许访问每一个路由

⑤ 守卫方法中 next 函数的 3 中调用方法:
⑴ 直接放行:next()
⑵ 强制其停留在当前页面:next(false)
⑶ 强制其跳转到登录页面:next('login')

⑥ 一个简单的登录案例
