路由
路由
1. 前端路由的概念与原理
1.1 什么是路由?
路由(router):对应关系。
1.2 什么是前端路由?
Hash地址与组件之间的对应关系。
1.3 SPA与前端路由
SPA:single page application单页面应用,一个web网站只有唯一的HTML页面,所有组件的展示与切换都在这一个唯一的页面上进行。
所以:不同组件之间的切换需要通过前端路由来实现。
1.4 前端路由的工作方式
- 用户点击了页面上的路由链接
- 导致URL地址栏中的Hash值发生了变化
- 前端路由监听到了Hash地址的变化
- 前端路由把当前Hash地址对应的组件渲染到浏览器中
2. vue-router的基本使用
vue-router是vue官方给出的路由解决方案
2.1 vue-router的安装和配置
安装vue-router:vue-router3.x只能配合vue2.x使用;vue-router4.x只能配合vue3.x使用
如果是用脚手架vue-cli来快速创建项目的,若在创建时选择了router则不需要额外安装。若不选择router,则需要在项目中npm i vue-router@版本号 -S;
创建路由模块index.js:在src下和components节点平行创建router模块,在router中创建index.js

在main.js中导入并挂载路由模块:

声明路由链接和占位符:在App根组件中,使用vue-router提供的router-link和router-view分别声明路由链接和占位符

声明路由匹配规则:在index.js路由模块中,通过routes数组声明路由的匹配规则

2.2 路由重定向redirect
使用场景:用户在访问地址A的时候,强制用户跳转到地址C,从而展示特定的组件界面
e.g.: 用户访问’/‘的时候,并没有对应的路由规则,通过redirect重定向属性可以强制跳转到’/home’,再渲染Home组件。
routes: [
{path: ‘/‘, redirect: ‘/home’}]
2.3 嵌套路由
可以通过路由实现组件的嵌套展示。
在组件中通过router-link和router-view声明子路由链接和子路由占位符

在路由模块index.js中通过children属性声明子路由规则

问题:现在在Movie组件下有三个子路由链接,但是不管点击哪个都想展示的是Movie组件,还要写三遍子路由链接,如果有n条就要写n遍,路由规则复用性差
2.4 动态路由
动态路由:将Hash地址中可变的部分定义为参数项,从而提高路由规则的可复用性。
e.g.
{path: ‘/movie/1’, component: Movie},
{path: ‘/movie/2’, component: Movie},
{path: ‘/movie/3’, component: Movie}
可以写为:
{path: ‘/movie/:id‘, component: Movie}
其中,:id就是动态参数项
注意: hash地址中
- / 后面的是路径参数, 通过this.$route.params访问
- ? 后面的是查询参数,通过this.$route.query访问
3. 声明式导航和编程式导航
- 点击链接实现导航的方式: 声明式导航,e.g.: 点击a链接跳转,vue项目中点击router-link等。
- 调用API实现导航的方式: 编程式导航,e.g.: 普通js中调用location.href跳转。
4. vue-router中的编程式导航API
- this.$router.push(‘hash地址’):跳转到指定hash地址,并增加一条历史记录
- this.$router.replace(‘hash地址’):跳转到指定hash地址,并替换掉当前的历史记录
- this.$router.go(n): 实现导航的前进、后退
$route和$router
- this.$route是路由的“参数对象”
- this.$router是路由的“导航对象”
5. 导航守卫
导航守卫的作用:控制路由的访问权限
导航守卫的使用场景:e.g. /main首页只有登陆后才能访问!

5.1 全局前置守卫
全局:全局生效
前置:从hash地址A->B,在跳转前就会触发守卫
全局前置守卫:每次发生路由的导航跳转时,都会触发全局前置守卫,可以对每个路由进行访问权限的控制。
在index.js中
const router = new VueRouter({…}); // 调用beforeEach方法即可声明全局前置守卫
router.beforeEach(fn);//每次路由导航发生跳转的时候都会触发fn回调函数
5.2 守卫方法fn的形参
全局前置守卫的回调函数中接收3个形参
router.beforeEach( (to, from, next) => {xxx})
- to: 将要访问的路由信息对象
- from:将要离开的路由信息对象
- next: 是一个函数,调用next()表示放行,允许导航通过,具体next函数的几种调用方式如下:
- 当用户拥有后台主页的访问权限,直接放行: next()
- 当用户没有后台主页的访问权限,强制调转到登录页面:next(‘/login’)
- 当用户没有后台主页的访问权限,不允许调转到后台主页: next(false)