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

路由是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,你就可以看到这个效果啦。

相关推荐
怕浪猫3 小时前
FDE 如何正确解决现场项目工程性的问题
前端·后端·ai编程
西瓜太郎12343 小时前
外层模型卡片与分组详情成功率不一致,应该怎么排查?
前端·typescript·go·软件工程·react
GreenTea3 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
毕业设计7036 小时前
(免费领源码) 基于微信小程序的预制菜商城的设计与实现25172-java、PHP、python、C#、小程序、大数据、单片机、网络工程等)
vue.js·python·mysql·微信小程序·pycharm·微信开发者工具·推荐算法
xifangge20256 小时前
AGENTS.md 怎么写?涵盖 Java、Python、Vue、Go 的 8 套开箱即用模板
java·vue.js·python
几何心凉6 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen6 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs7 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马8 小时前
从零到实战,完整AI学习路线
前端
三十而立洋8 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化