vue3 导航守卫

本文详细介绍了Vue3中的导航守卫,包括全局前置/后置守卫、路由独享守卫以及组件内守卫的使用,强调了响应式系统和CompositionAPI带来的新特性。
摘要由CSDN通过智能技术生成

Vue 3 的导航守卫与 Vue 2 相比,在 API 和使用方式上并没有太大的变化,但 Vue 3 的响应式系统和 Composition API 为导航守卫提供了更多的灵活性。
以下是 Vue 3 中常见的几种导航守卫:

1. 全局前置守卫

全局前置守卫在路由跳转前执行。你可以使用 【router.beforeEach】 注册一个全局前置守卫:

import { createRouter, createWebHistory } from 'vue-router'  
  
const router = createRouter({  
  history: createWebHistory(),  
  routes: [/* ...你的路由对象... */],  
})  
router.beforeEach((to, from, next) => {  
  // 在这里执行你的逻辑  
  // 例如,检查用户是否已登录  
  const isLoggedIn = /* ...获取是否登录的逻辑.. */;  
  if (isLoggedIn) {  
    next(); // 允许路由跳转  
  } else {  
    next('/login'); // 阻止路由跳转,并重定向到登录页面  
  }  
})

2. 全局后置守卫

全局后置守卫在路由跳转后执行。你可以使用 【router.afterEach】 注册一个全局后置守卫:

router.afterEach((to, from) => {  
  // 在这里执行你的逻辑  
  // 例如,发送一个分析事件  
  analytics.trackPageView(to.path);  
})

3. 路由独享的守卫

你可以在每个路由配置对象中定义 【beforeEnter 】守卫:

const routes = [  
  {  
    path: '/user/:id',  
    component: User,  
    beforeEnter: (to, from, next) => {  
      // 在这里执行你的逻辑  
      // 例如,检查用户是否有权限访问该页面  
      const hasPermission = /* ...获取你的权限.. */;  
      if (hasPermission) {  
        next();  
      } else {  
        next('/forbidden');  
      }  
    },  
  },  
  // ... 其他路由  
]

4. 组件内的守卫

在组件内部,你可以使用 【beforeRouteEnter、beforeRouteUpdate 和 beforeRouteLeave】守卫:

<script>  
import { onBeforeRouteEnter, onBeforeRouteUpdate, onBeforeRouteLeave, ref } from 'vue';  
  
export default {  
  setup() {  
    const someData = ref(null);  
  
    // 组件被渲染前调用  
    onBeforeRouteEnter((to, from, next) => {  
      // 注意:这里不能访问组件的响应式状态或 `setup` 中的局部变量  
      // 因为组件实例还没有被创建  
      next(vm => {  
        // 当组件实例创建后,可以通过 vm 访问  
        // 但通常我们不需要这么做,因为守卫逻辑可以在 `setup` 中处理  
      });  
    });  
  
    // 当前路由改变,但组件被复用时调用  
    onBeforeRouteUpdate((to, from, next) => {  
      // 可以访问 `setup` 中的响应式状态  
      console.log('Route updated:', to.path);  
      next();  
    };  
  
    // 导航离开组件时调用  
    onBeforeRouteLeave((to, from, next) => {  
      // 可以访问 `setup` 中的响应式状态  
      if (someData.value) {  
        const answer = window.confirm('你确定要离开吗?你的数据尚未保存。');  
        if (answer) {  
          next();  
        } else {  
          next(false);  
        }  
      } else {  
        next();  
      }  
    };  
  
    // 组件的逻辑...  
    // 返回响应式状态或其他计算属性、方法等  
    return {  
      someData,  
      // ...  
    };  
  },  
};  
</script>

注意项

1. 注意next的使用,不能在一个导航钩子内调用两次!!
以下错误示例:
// 错误示例
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // 如果用户未能验证身份,则 `next` 会被调用两次
  next()
})

2. next 函数必须被调用,否则导航将不会解析或更新 URL3. 在全局守卫和路由独享的守卫中,next 函数接受一个位置参数,表示要导航到的下一个位置。
next({ name: 'Login' })  //导航到name为Login的路由
4. 如果传入 false,则导航会被终止。
next(false)  //终止导航
5. 在组件内的守卫中,beforeRouteEnter 守卫的 next 函数接受一个回调函数作为参数,
   该回调函数在组件实例被创建后执行。如下:
 next(vm => {  
  // 当组件被渲染后,你可以通过 `vm` 访问组件实例  
 });  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

**之火

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值