路由守卫:五星级路由必不可少

路由是vue实现单页应用的关键之一,Vue Router是vue官方提供的路由管理器,负责管理应用中的多个视图和导航,也就是页面切换。确保了用户在 应用内的导航能够丝滑的从一个视图,切换到另一个视图,同时修改URL地址。但是,它怎么切换,能不能切换,这是随意的吗?我可以随便去到有用户核心数据的页面(比如购物车)吗?答案当然是否定的。今天我们将介绍路由守卫,来一个五星级路由吧!

参数概念

在路由守卫中,接收的参数通常为from、to、next,在不同的路由守卫中被使用,用来帮助控制导航行为和执行相关的逻辑。

  • from:表示当前将要离开的路由,代表一个路由对象,包含了即将离开的路由信息,比如,我们从/home路由去到。/about路由,from代表的就是/home的路由对象。它有这个路由对象的所有方法和属性(path、name、params、query、hash...)。
  • to:表示当前导航将要到达的目标路由,也是一个路由对象。比如上面的/about就是to路由对象
  • next:这是一个函数,用于指示导航应该继续还是停止,决定了路由守卫的下步行为。
    • 直接调用next()函数,表示没有拦截,允许导航继续到目标路由。
    • next(false):取消当前导航,将立即终止当前导航。
    • next('/'):传入想要到达的新路径。例如,让你没有登入,想要去到购物车页面,进行权限校验后,next的参数应该为next('/login')去到登录页面进行登录。

路由守卫的类型和使用

全局前置守卫(beforeEach)

  • 概念:在每个路由跳转之前都会被调用
  • 主要用途:可以用来进行全局的权限校验或者进行初始化

使用示例:

javascript 复制代码
import { createRouter, createWebHistory } from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';
import SecretPage from './views/SecretPage.vue';

const routes = [
  { 
      path: '/', 
      component: Home 
  },
  { 
      path: '/about', 
      component: About 
  },
  {
    path: '/secret',
    component: SecretPage,
    meta: { 
        requiresAuth: true 
    }
  }
];

const router = createRouter({
    history: createWebHistory(),
    routes
});

// 全局前置守卫
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // 如果当前路由需要权限校验
    if (!localStorage.getItem('userLoggedIn')) {
      // 如果没有登录,重定向到登录页面
      next({ path: '/login' });
    } else {
      // 如果已登录,继续导航
      next();
    }
  } else {
    // 不需要权限校验,直接继续
    next();
  }
});

export default router;

设置路由的前置守卫,通过meta属性,判断to路由是否需要权限校验,需要这进行权限校验,这里使用localStorage存储登录信息,模拟登录,没有登录的话,将next函数的参数设为指定的路径,需要传参时用对象的方式,不需要传参可以简写为'/login'

全局解析守卫(beforeResolve)

  • 概念:在全局前置守卫之后、路由被确认之前被调用
  • 主要用途:用于异步数据的获取,确保在路由被确认之前,拿到所需要的数据(API数据、本地存储数据、缓存数据、第三方服务数据......)。

使用示例:

vbnet 复制代码
router.beforeResolve(async (to, from, next) => {
    if (to.matched.some(record => record.meta.needsData)) {
      try {
        // 异步数据获取
        const data = await fetchData(to.params.id); 
        next();
      } catch (error) {
        // 错误处理
        next('/404'); //错误页面
      }
    } else {
      next();
    }
  });
  
  async function fetchData(id) {
    异步请求函数
    ......
  }

避免请求数据出错导致的程序崩溃。

全局后置守卫(afterEach)

  • 概念:每个路由跳转完成后被调用
  • 主要用途:通常用于执行后置操作,比如,修改页面标题、记录页面浏览历史......

使用示例:

ini 复制代码
router.afterEach(()=>{
    document.title = to.meta.title
})

组件内的守卫

概念:主要用于处理组件级别的逻辑,如数据预加载、生命周期钩子、以及在路由跳转前后执行的特定操作,这些守卫可以让你组件级别控制路由的跳转行为。

  • beforeRouteEnter:当前路由开始之前调用,不能访问this(指向该组件实例),因为组件实例还没有创建,用于组件被创建之前获取数据或者执行初始化操作。
  • beforeRouteUpdate:在当前路由改变,该组件被复用时,比如一个详情页跳转到另一个详情页,使用的相同的组件。通常用于数据改变时执行的逻辑,可以访问this。
  • beforeRouteLeave:当前路由即将离开时调用,用于在离开组件之前进行确认操作,比如询问用户是否在离开前保存了做出的数据更改,可以访问this。

使用示例:

xml 复制代码
<template>
  <div>
    <h1>Secret Page</h1>
    <p>Welcome, {{ user.name }}!</p>
  </div>
</template>

<script setup>
import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router';
let user = null;
onBeforeRouteEnter((to, from, next) => {
  // 这里可以预加载数据或做其他初始化工作
  fetchUserData(next);
});

onBeforeRouteLeave((to, from, next) => {
  // 通常用于确认用户是否想要离开页面
  confirm('离开前确认保存数据成功') ? next() : next(false);
});

function fetchUserData(next) {
  // 从服务器获取用户数据
  const fetchedUser = { name: 'John Doe' };
  user = fetchedUser;
  if (next) {
    next();
  }
}
</script>

在完成五星级路由,还要加上一点提示信息,避免页面跳转时,加载时间过长,避免用户以为按钮失效,疯狂点击的情况。我们用上nprogress轻量级进度条插件。

复制代码
npm install nprogress

在路由管理中

javascript 复制代码
import NProgress from 'nprogress'; // 导入 NProgress
import 'nprogress/nprogress.css'; // 导入 NProgress 的 CSS

在两个路由守卫中,使用nprogress,你就可以看到这个效果啦。

相关推荐
10年前端老司机2 小时前
什么!纯前端也能识别图片中的文案、还支持100多个国家的语言
前端·javascript·vue.js
摸鱼仙人~2 小时前
React 性能优化实战指南:从理论到实践的完整攻略
前端·react.js·性能优化
程序员阿超的博客3 小时前
React动态渲染:如何用map循环渲染一个列表(List)
前端·react.js·前端框架
magic 2453 小时前
模拟 AJAX 提交 form 表单及请求头设置详解
前端·javascript·ajax
小小小小宇7 小时前
前端 Service Worker
前端
只喜欢赚钱的棉花没有糖8 小时前
http的缓存问题
前端·javascript·http
小小小小宇8 小时前
请求竞态问题统一封装
前端
loriloy8 小时前
前端资源帖
前端
源码超级联盟8 小时前
display的block和inline-block有什么区别
前端
GISer_Jing8 小时前
前端构建工具(Webpack\Vite\esbuild\Rspack)拆包能力深度解析
前端·webpack·node.js