vue导航守卫详解

全局前置守卫

router.beforeEach((to,form,next)=>{
    // to:到哪里去(即将要进入的目标-to.path),form:从哪里来(当前导航正要离开的路由)
    // 可选的第三个参数next vue3中不推荐使用next来表示放行的路径,(了解即可)
    // 跳转到login页面 || 取消当前导航,如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到路由对应的地址。|| 不做任何处理 在vue3中可以不写,或者写上return true
	return '/login' || return false || return true
})

全局解析守卫

// 这和 router.beforeEach 类似,因为它在 每次导航时都会触发,但是确保在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被正确调用
// router.beforeResolve 是获取数据或执行任何其他操作(如果用户无法进入页面时你希望避免执行的操作)的理想位置。
// 具体参数及参数用法参考beforeEach
router.beforeResolve(async to => {
  if (to.meta.requiresCamera) {
    try {
      await askForCameraPermission()
    } catch (error) {
      if (error instanceof NotAllowedError) {
        // ... 处理错误,然后取消导航
        return false
      } else {
        // 意料之外的错误,取消导航并把错误传给全局处理器
        throw error
      }
    }
  }
})

全局后置守卫

// 这个钩子守卫不会接受 next 函数,而且也不会改变导航本身
// 它们对于分析、更改页面标题、声明页面等辅助功能以及许多其他事情都很有用。
router.afterEach((to, from) => {})

路由独享守卫

const routes = [
  {
    path: '/user/:id',
    component: User,
    beforeEnter: (to, from) => {
     // 跳转到login页面 || 取消当前导航,如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到路由对应的地址。|| 不做任何处理 在vue3中可以不写,或者写上return true
    // 可以急用to.query.XXX获取地址栏中传的参数,从而进行业务操作
    // beforeEnter 守卫 只在进入路由时触发,不会在 params、query 或 hash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects。它们只有在 从一个不同的 路由导航时,才会被触发。
     return '/login' || return false || return true
    },
  },
]
// 也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用:
function removeQueryParams(to) {
  if (Object.keys(to.query).length)
    return { path: to.path, query: {}, hash: to.hash }
}
const routes = [
  {
    path: '/user/:id',
    component: User,
    beforeEnter: [removeQueryParams]
  }
]

组件内的守卫

可用的配置 API

你可以为路由组件添加以下配置:

  • beforeRouteEnter
  • beforeRouteUpdate
  • beforeRouteLeave
const UserDetails = {
  template: `...`,
  beforeRouteEnter(to, from) {
    // 在渲染该组件的对应路由被验证前调用
    // 不能获取组件实例 `this` !
    // 因为当守卫执行时,组件实例还没被创建!
    // beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。  
  },
  beforeRouteUpdate(to, from) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
    // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from) {
    // 在导航离开渲染该组件的对应路由时调用
    // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
    // 这个 离开守卫 通常用来预防用户在还未保存修改前突然离开。该导航可以通过返回 false 来取消。
    // 可以在这个里边
  },
}

导航守卫

import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'

<script setup lang="ts">
    // 组合式 API 守卫也可以用在任何由 <router-view> 渲染的组件中,它们不必像组件内守卫那样直接用在路由组件上。
    // 与 beforeRouteLeave 相同,无法访问 `this`
    onBeforeRouteLeave((to, from) => {
      const answer = window.confirm(
        'Do you really want to leave? you have unsaved changes!'
      )
      // 取消导航并停留在同一页面上 强制留到某个页面,无法后退跳转
      if (!answer) return false
    })

    const userData = ref()

    // 与 beforeRouteUpdate 相同,无法访问 `this`
    onBeforeRouteUpdate(async (to, from) => {
      //仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改
      if (to.params.id !== from.params.id) {
        userData.value = await fetchUser(to.params.id)
      }
    })
</script>

详情见:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html


标题:vue导航守卫详解
作者:mcwu
地址:http://mcongblog.com/articles/2023/03/30/1680505194886.html

    评论
    2 评论
    2023-08-04 16:33 回复»

    感谢支持~~~

    2023-06-15 08:28 回复»

    给力噢👍🏻

avatar

取消