Vue-Router路由守卫详的细用法教程

 更新时间:2024年12月03日 10:34:30   作者:景天科技苑  
在Vue.js应用中,Vue-Router是一个非常重要的插件,它允许我们实现页面间的导航,然而,仅仅实现导航是不够的,我们还需要在导航的不同阶段进行各种操作,本文将结合实际案例,详细介绍Vue-Router路由守卫的用法,需要的朋友可以参考下

引言

在Vue.js应用中,Vue-Router是一个非常重要的插件,它允许我们实现页面间的导航。然而,仅仅实现导航是不够的,我们还需要在导航的不同阶段进行各种操作,如用户认证、权限管理、数据预加载等。这时,路由守卫就派上了用场。本文将结合实际案例,详细介绍Vue-Router路由守卫的用法。

一、路由守卫的基本概念

路由守卫是Vue-Router提供的一种机制,用于在路由跳转前或跳转后执行一些操作。它类似于Vue组件中的生命周期钩子函数,但它是针对路由的。通过路由守卫,我们可以在用户访问特定路由前或离开 特定路由后执行一些逻辑,从而控制用户访问权限、加载数据或取消导航等操作。

Vue-Router中的路由守卫主要分为三类:全局守卫、路由独享守卫和组件内守卫。

  • 全局守卫:在整个应用的任何路由跳转前或跳转后执行。全局守卫适用于应用级别的逻辑,如用户登录状态检查。
  • 路由独享守卫:在特定路由跳转前或跳转后执行。路由独享守卫适用于特定路由的逻辑,如管理员权限检查。
  • 组件内守卫:定义在组件内部的守卫,它分为beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave。组件内守卫适合与组件自身相关的逻辑,如数据预加载和页面离开确认。

二、全局守卫

全局守卫是在Vue Router实例上注册的,可以对所有路由变化进行监听。全局守卫包括全局前置守卫(beforeEach)、全局解析守卫(beforeResolve)和全局后置守卫(afterEach)。

  • 全局前置守卫(beforeEach)

全局前置守卫在每次导航之前调用,常用于检查用户是否登录以及用户权限验证等。

示例代码:

import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home';
import About from '@/components/About';
import Login from '@/components/Login';

Vue.use(Router);

const router = new Router({
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About, meta: { requiresAuth: true } },
    { path: '/login', component: Login }
  ]
});

// 假设我们有一个检查用户是否登录的函数
function isUserLoggedIn() {
  // 这里可以是一个实际的登录检查逻辑,比如查询cookie或Vuex状态
  return false; // 这里我们假设用户未登录
}

// 全局前置守卫
router.beforeEach((to, from, next) => {
  // 检查目标路由是否需要认证
  if (to.meta.requiresAuth && !isUserLoggedIn()) {
    // 如果需要认证且用户未登录,则跳转到登录页
    next('/login');
  } else {
    // 否则允许访问
    next();
  }
});

export default router;

在上面的示例中,我们定义了一个全局前置守卫,它会在每次路由跳转前检查目标路由是否需要认证(通过meta属性中的requiresAuth标识)。如果需要认证且用户未登录,则重定向到登录页。

  1. 全局解析守卫(beforeResolve)

全局解析守卫在导航被确认前调用,常用于异步获取数据后再渲染组件的场景。这个守卫与全局前置守卫类似,但它在导航被确认之前被调用,这意味着它可以在导航被阻止之前解析数据。

示例代码:

router.beforeResolve((to, from, next) => {
  // 在这里进行异步数据获取操作
  // 比如通过API请求获取数据
  console.log('导航即将被确认,可以进行数据获取操作');
  next();
});

在上面的示例中,我们在全局解析守卫中进行了数据获取操作。注意,这个守卫不会中断导航过程,它只是用于在导航确认之前进行数据获取。

  1. 全局后置守卫(afterEach)

全局后置守卫在每次导航之后调用,常用于统计页面PV、修改页面title等操作。这个守卫不接受next函数,也不可以中断导航。

示例代码:

router.afterEach((to, from) => {
  // 在这里进行页面title设置等操作
  document.title = to.meta.title || '默认标题';
  console.log('导航已完成');
});

在上面的示例中,我们在全局后置守卫中设置了页面title,并打印了导航完成的消息。

三、路由独享守卫

路由独享守卫是在路由配置中直接定义的守卫,它只应用于单个路由或一组路由。这种守卫允许我们针对特定的路由实施一些逻辑,如验证用户是否有权限访问某个页面。

示例代码:

const routes = [
  {
    path: '/admin',
    component: Admin,
    meta: { requiresAuth: true, requiresAdmin: true },
    beforeEnter: (to, from, next) => {
      // 假设我们有一个检查用户是否登录和是否具备管理员权限的函数
      function isUserLoggedIn() { return false; } // 用户未登录
      function isUserAdmin() { return true; } // 用户是管理员(这里只是模拟)

      // 检查用户是否登录
      if (to.meta.requiresAuth && !isUserLoggedIn()) {
        // 如果需要认证且用户未登录,则重定向到登录页
        next('/login');
      } else if (to.meta.requiresAdmin && !isUserAdmin()) {
        // 如果需要管理员权限且用户不是管理员,则重定向到无权限页面
        next('/403');
      } else {
        // 否则允许访问
        next();
      }
    }
  }
];

const router = new Router({
  routes
});

在上面的示例中,我们定义了一个路由独享守卫,它会在进入/admin路由前检查用户是否登录和是否具备管理员权限。如果需要认证且用户未登录,则重定向到登录页;如果需要管理员权限且用户不是管理员,则重定向到无权限页面。

四、组件内守卫

组件内守卫是在组件内定义的守卫,它分为beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave。

  1. beforeRouteEnter

在进入路由前执行,可以在这里进行数据预加载等操作。由于组件实例在守卫执行时还未被创建,因此不能访问this。可以通过将回调传递给next函数来访问组件实例。

示例代码:

export default {
  name: 'MyComponent',
  beforeRouteEnter(to, from, next) {
    // 在进入路由前执行数据预加载等操作
    console.log('准备进入MyComponent组件');
    next(vm => {
      // 访问组件实例
      vm.fetchData();
    });
  },
  methods: {
    fetchData() {
      // 数据加载逻辑
      console.log('加载数据');
    }
  }
};

在上面的示例中,我们在beforeRouteEnter守卫中进行了数据预加载操作,并通过回调访问了组件实例以调用数据加载方法。

  1. beforeRouteUpdate

在当前路由改变时执行,但组件实例被复用。这可以用于响应路由参数的变化。

示例代码:

export default {
  name: 'MyComponent',
  beforeRouteUpdate(to, from, next) {
    // 在路由变化时执行数据更新等操作
    console.log('MyComponent组件的路由正在更新');
    this.fetchData(); // 调用数据更新方法
    next();
  },
  methods: {
    fetchData(params) {
      // 根据新的路由参数加载数据
      console.log('根据新参数加载数据');
    }
  }
};

注意:在上面的示例中,我们假设fetchData方法可以接受参数,但beforeRouteUpdate守卫并没有直接传递参数给fetchData方法。在实际应用中,你可能需要根据路由参数的变化来动态加载数据,这时你可以在beforeRouteUpdate守卫中获取新的路由参数并传递给fetchData方法。

  1. beforeRouteLeave

在离开当前路由前执行,可以用于提示用户是否确认离开当前页面。

示例代码:

export default {
  name: 'MyComponent',
  data() {
    return {
      hasUnsavedChanges: false // 用于标识是否有未保存的更改
    };
  },
  beforeRouteLeave(to, from, next) {
    // 在离开当前路由前执行确认操作
    if (this.hasUnsavedChanges) {
      // 提示用户是否确认离开
      const answer = window.confirm('你有未保存的更改,确认离开吗?');
      if (answer) {
        next(); // 用户确认离开,允许导航
      } else {
        next(false); // 用户取消离开,阻止导航
      }
    } else {
      next(); // 没有未保存的更改,允许导航
    }
  }
};

在上面的示例中,我们在beforeRouteLeave守卫中检查是否有未保存的更改,并提示用户是否确认离开。如果用户确认离开,则允许导航;否则,阻止导航。

到此这篇关于Vue-Router路由守卫详的细用法教程的文章就介绍到这了,更多相关Vue-Router路由守卫内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue2.0 常用的 UI 库实例讲解

    vue2.0 常用的 UI 库实例讲解

    这篇文章主要介绍了vue2.0 常用的 UI 库实例讲解,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-12-12
  • Vue中使用Swiper简单封装组件示例

    Vue中使用Swiper简单封装组件示例

    这篇文章主要为大家介绍了Vue中使用Swiper简单封装组件示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • Vue使用formData类型上传文件

    Vue使用formData类型上传文件

    这篇文章主要介绍了Vue使用formData类型上传文件方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Vue如何实现打包资源按时间戳方式

    Vue如何实现打包资源按时间戳方式

    这篇文章主要介绍了Vue如何实现打包资源按时间戳方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • Vue函数式组件专篇深入分析

    Vue函数式组件专篇深入分析

    Vue提供了一种称为函数式组件的组件类型,用来定义那些没有响应数据,也不需要有任何生命周期的场景,它只接受一些props来显示组件,下面这篇文章主要给大家介绍了关于Vue高级组件之函数式组件的使用场景与源码分析的相关资料,需要的朋友可以参考下
    2023-01-01
  • Vue Element-UI中el-table实现单选的示例代码

    Vue Element-UI中el-table实现单选的示例代码

    在element-ui中是为我们准备好了可直接使用的单选与多选属性的,本文主要介绍了Vue Element-UI中el-table实现单选的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • vue中对监听esc事件和退出全屏问题的解决方案

    vue中对监听esc事件和退出全屏问题的解决方案

    这篇文章主要介绍了vue中对监听esc事件和退出全屏问题的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • vue-cli脚手架引入弹出层layer插件的几种方法

    vue-cli脚手架引入弹出层layer插件的几种方法

    layer.js(mobile)是一个小巧方便的弹出层插件,在之前的apicloud项目中被大量使用,但最近对apicloud的IDE、非常不友好的文档和极低的开发效率深感厌烦,决定弃用然后转向Vue开发。这篇文章主要介绍了vue-cli脚手架引入弹出层layer插件的几种方法,需要的朋友可以参考下
    2019-06-06
  • Vue中对watch的理解(关键是immediate和deep属性)

    Vue中对watch的理解(关键是immediate和deep属性)

    watch侦听器,是Vue实例的一个属性,是用来响应数据的变化,需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的,这篇文章主要介绍了Vue中对watch的理解,需要的朋友可以参考下
    2022-11-11
  • vue制作加载更多功能的正确打开方式

    vue制作加载更多功能的正确打开方式

    这篇文章是一篇Vue.js的教程,目标在于用一种常见的业务场景——分页/无限加载,以及编写过程中自己的错误写法,分享给大家,帮助读者更好的理解Vue.js中的一些设计思想。
    2016-10-10

最新评论