先上一个简单的路由配置,和vue2 还是有区别

import { createRouter, createWebHistory } from 'vue-router'
const routes = [
	{ path: '/', redirect: '/login' },
	{
		path: '/login',
		name: 'login',
		component: () => import('../views/login/index.vue'),
	},
    {
        path : '/main',
        name : 'main',
        component : () => import('../views/main/index.vue')
    }
]
const webHistory = createWebHistory()
const router = createRouter({
	history: webHistory,
	routes,
})
export default router

vue-router官网的顺序

一. beforeEach (全局前置守卫) (中文翻译 : 在…之前 . 每个)

  router.beforeEach((to, from) => {
        console.log(to)
        console.log(from)
       // 返回true / false 用来标识导航能否顺利进行
        return true
  })

解析 :
to / from 返回一个对象

参数中有两个属性 fullPath / path 。
前者是地址带参数 , 后者是地址不带参数
如果参数中有字符 例如 :

fullPath: '/main?a=%E5%8F%82%E6%95%B01&b=%E5%8F%82%E6%95%B02'

可以用 decodeURIComponent 进行解码 去进行参数参数传递
再来说说参数 next , 在我们做登录判定的时候 , 要确定缓存里面是否含所有登录标识 , 或者其他可以判定的登录方法 , 如果没有登录标识 , 我们就可以 利用 next 跳转回去让用户进行登录 看代码 :

router.beforeEach((to, from , next) => {
    // 判断是否含有登录标识
        const isLogin = !!sessionStorage.getItem('isLogin')
        // 想要跳转到 person页面 但是没有标识 就next 去登录
         if(to.name === 'person' && !isLogin){
              next({ name : 'login' })
        // 想要跳转到 main页面 但是没有标识 就next 去登录
         }else if(to.name === 'main' && !isLogin) {
             next({name:'login'})
         }else {
             next()
         }
  })

二 ,全局解析守卫 beforeResolve (中文翻译 :(在…之前 决定 )

router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,因为它在 每次导航时都会触发,但是确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用。
给出一个官网的例子我们来分析分析它

router.beforeResolve(async to => {
  if (to.meta.requiresCamera) {
    try {
      await askForCameraPermission()
    } catch (error) {
      if (error instanceof NotAllowedError) {
        // ... 处理错误,然后取消导航
        return false
      } else {
        // 意料之外的错误,取消导航并把错误传给全局处理器
        throw error
      }
    }
  }
})

解析 :
1.确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后(重点 )
2.router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。(重点)

再结合上面的实例我们分析一下,
是这么个意思。
1.首先页面加载 , 目前还不知道页面是否加载完全 , 就去执行这个路由回调
2.去检查meta里面有requiresCamera这个属性,如果有就执行 askForCameraPermission()这个方法并且页面跳转 ,没有就不让页面跳转

在针对上面的两个重点来分析
可以简写成: 看看是不是所有的组件内守卫和异步路由组件被解析了通过判断一个条件,如果没有被解析 ,进行什么操作 , 如果解析成功了,进行什么操作(如有错误还请指正)

三.全局后置钩子 afterEach (中文翻译 : (在…之后 每个))

router.afterEach((to,from)=>{
    to.fullPath = '12345'
    to.query = {
        ...to.query,
        num : 12345 // 新添加的数据
    }
})

解析 :

  1. 回调函数的参数是没有 next 这个函数参数的
  2. 作用 :你可以获取到下一个页面的参数,并且对这些参数加工处理 ,用官网的话来说就是 : 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。

总结下这些全局守卫
1.都是接收一个函数进行传参 , 而且都是在创建出来的router实例上面去调用方法传递参数
2.全局前置守卫 , 主要用于做一些判定页面跳转的工作
3 全局解析守卫 , 对与页面未加载完成之前 ,利用条件去进行判断页面是否加载完全 , 加载完全了执行业务 逻辑,未加载完全 ,执行业务逻辑 。
4.全局后置守卫 , 对于跳转的目标页面已经定下了 , 就不需要next 了 ,可以对目标页面的数据进行逻辑处理在传入下一个页面 。

==================================================

全局守卫我们聊完了,就来聊聊 路由独享守卫

const routes = [
	{ path: '/', redirect: '/login' },
	{
		path: '/login',
		name: 'login',
		component: () => import('../views/login/index.vue'),
	},
	{
		path: '/main',
		name: 'main',
		component: () => import('../views/main/index.vue')
	},
	{
		path: '/person',
		name: 'person',
		component: () => import('../views/personal/index.vue'),
	},
]

1.路由独享守卫 beforeEnter (中文翻译 : 在…之前 进入)

	{
		path: '/main',
		name: 'main',
		component: () => import('../views/main/index.vue'),
		// 注意添加的位置
        beforeEnter : (to,from,next) => {
            window.console.log(to),
            window.console.log(from)
            window.console.log(next)
            // return false  // 取消导航跳转
            next()
        }
	}

解析 : 根据官网解析 , 只有在 路由变化的时候才会去激发路由独享守卫( params、query 或 hash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects 不会触发 )
接收三个参数 to from next 触发实际 在 全局前置守卫 之后 , 全局解析守卫之前

============================================

下面在看看三个组件内部守卫
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave

export default {
  setup() {},
  mounted(){
  },
  methods: {
    goBack() {
      this.$router.go(-1)
    },
  },
//  组件内守卫
beforeRouteEnter(to ,from , next){
    // next() 可以通过内部的回调函数访问实例
     // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
    window.console.log(this) // undefined
    window.console.log(to)
    window.console.log(from)
    next((e)=> {
        window.console.log(e) // 当前的this
    })
},
beforeRouteUpdata(to ,from){
    // 无 next 
     // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
    window.console.log(this)
    window.console.log(to)
    window.console.log(from)
},
beforeRouteLeave(to ,from){
    // 无 next
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
    window.console.log(this)
    window.console.log(to)
    window.console.log(from)
},
}

解析 : 这三个差不多就放在一起还有个对照
1.首先来说说执行时机 : 路由独享守卫的后面 调用这三个守卫 。
2. 书写位置 : 在单个vue文件内部 , 与 methods , 等 api 同级
3. 只有 beforeRouteEnter 参数 有 next , 因为这个路由不能访问this ,于是就有了next 函数 , 可以向里面传递一个回调函数 , 回调函数的参数就是 this , 可以看代码, 其他两个组件内部守卫 都可以的访问this , 所以就没有必要在去加next ,(官网意思就是这个)

如果有不正确的地方欢迎批评指正

在setup组合式api 里面的写法在这里就先不讨论了

Logo

前往低代码交流专区

更多推荐