一、介绍 Vue-Router

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。

二、钩子函数

先编写好 router 路由内部,方便接下来的钩子函数进行讲解

// 引入vue-router
import VueRouter from 'vue-router'
// 引入四个路由界面
import Home from '../pages/Home'
import Shop from '../pages/Shop'
import Login from '../pages/Login'
import Admin from '../pages/Admin'
// 设置一个变量保存实例(方便讲解)
const Router = new VueRouter({
	routes:[
		{
			path:'/home',
			component:'Home',
			meta:{
				//	是否需要登录后才能访问
				isVerify:false
			}
		},
		{
			path:'/shop',
			component:'Shop',
			meta:{
				isVerify:true
			}
		},
		{
			path:'/admin',
			component:'Admin',
			meta:{
				isVerify:true
			}
		},
		{
			path:'/login',
			component:'Login',
			meta:{
				isVerify:false
			}
		}
	]
})
//	全局暴露路由实例
export default Router

注意:同一类型守卫函数在全局和局部都定义了,它们的执行顺序是先执行全局,再执行局部,局部守卫一般是一个函数,二全局守卫一般是一个对象(传入的是 callback 函数)

2.1 beforeEach(全局前置路由)

对所有的路由都生效,每次跳转之前都会执行
应用场景:用户尝试绕过登录,通过修改 URL 进入页面 时触发,没有登录信息则重定向到 Login 页面

// 在 vue-Router 实例上设置,除开 Login 路由其他页面都要验证是否有 token
Router.beforeEach((to,from,next) => {
	if(to.meta.isVerify){
		if(!hasPermission()){
			// 重定向到登录页
			next('/login')
		}else{
			next();		// 允许跳转
		}
	}else{
		next()
	}
})

让我们看一下 to 和 from 里面有什么?

初始页 跳转到 Home 页面

console.log(to,from)	// object,object

在这里插入图片描述
可以看到 to 和 from 都是一个 Object 对象 ,里面存储着路由的各种属性

2.2 beforeEnter(路由独享守卫)

可以在路由配置上定义 独享 的前置守卫,与全局前置守卫的方法参数是一样的

//	Admin 路由内部
{
	path:'/admin',
	component:'Admin',
	beforeRouteEnter(to,from,next){
		if(//判断是否管理员){
			//	是的话
			next()
		}
	}
}
2.3 beforeRouteEnter(独享路由守卫)

版本 2.5新增 对设置的路由生效,在 进入(激活)路由前 被调用,由于路由跳转先于组件实例的创建,因此无法访问实例 this

作用和 beforeEnter 类似,但是这个钩子函数可以进行 异步操作 (异步请求数据)
//	shop 路由内部
{
	path:'/shop',
	component:'Shop',
	async beforeRouteEnter(to,from,next){
		//	利用 await 执行时 , 会阻塞同层的代码执行原理
		await this.requireData()
		// 通过回调函数访问组件实例
		next( vm => {
            // 在回调函数中访问组件实例
            vm.loadData();			
		})
	}
}
2.4 beforeResolve(全局解析路由)

导航被确认之前,路由组件被解析之后调用

应用场景:可以进行一些需要在路由切换之前执行的异步操作,比如数据的预处理或者加载,类似 生命周期 beforeCreated

很多人觉得没什么用,我之前在做项目遇到过一个场景——没有后端,所有数据都来源开放API , 由于二次封装时把 baseURL 写死了,导致向 API 发送请求仅限于一个网站,灵活性很差,如果利用 beforeResolve 来修改 baseURL 的话 ,这个问题就变得很简单


//根据页面功能的不同,修改 baseURL 使得代理服务器代发 /api 时能够访问到多个网站的 API
router.beforeResolve((to, from, next) => {
  let url;
  if (to.path === '/login') {
    url = "https://A.com";
  }
  if (to.path === "/home") {
    url = "https://B.com";
  }
  if (to.path === "/Admin") {
    url = "https://C.com";
  }
  axios.defaults.baseURL = url;
  next();
})

通过修改 axios.defaults.baseURL 就可以在组件数据加载之前修改好请求地址,及时发送请求数据,然后开始渲染数据

2.5 afterEach(全局后置路由)

每次路由成功跳转之后都会被调用,没有 next函数 也不会改变导航本身

router.afterEach((to, from) => {
	// 没有 next() 方法
})

2.6 beforeRouteLeave(路由独享后置守卫)

局部路由离开当前路由时触发
应用场景处理当前路由用户 未提交的表单数据,关闭定时器

export default({
	name:'shop',
	beforeRouteLeave(to,from,next){
		//	在从 /shop/1 跳转 /shop/2 时触发,组件再次渲染,只是参数发送变化
		// 可以访问 this
	}
})

三、额外的钩子函数

beforeRouteUpdate

当前路由复用 时,当前函数设置动态参数(例如从params变化,’ /shop:id ')时执行,可以用于更新数据等操作

//直接在组件中使用
export default({
	name:'home',
	beforeRouteUpdate(to,from,next){
		//	在从 /shop/1 跳转 /shop/2 时触发,组件再次渲染,只是参数发送变化
		// 可以访问 this
	}
})
这是执行顺序

在这里插入图片描述

最后在配上自己画的流程图:

在这里插入图片描述

更多推荐