返回

vue-router 守卫模式

前端

Vue 路由守卫:理解三种模式及其应用场景

简介

Vue 路由守卫是一种强大的机制,可用于在 Vue.js 应用程序中管理和自定义路由导航。通过在不同时刻(例如,进入或离开路由时)拦截路由导航,守卫允许开发者执行各种任务,例如身份验证、数据获取和权限控制。

守卫模式

Vue 路由提供了三种类型的守卫,每种类型都有其特定的应用场景:

1. 全局守卫

全局守卫适用于整个应用程序,并在任何路由导航发生时触发。它们通常用于强制执行全局政策,例如身份验证和数据预取。

beforeEach :在进入任何路由之前触发。
beforeResolve :在解析所有组件和异步路由之前触发。
afterEach :在成功导航到新路由之后触发。

2. 组件内守卫

组件内守卫只适用于特定组件,并在该组件的路由导航发生时触发。它们通常用于组件特定的任务,例如权限控制和数据请求。

beforeRouteEnter :在进入组件之前触发,并在其嵌套组件解析之前。
beforeRouteLeave :在离开组件之前触发,并在其嵌套组件销毁之后。

3. 路由独享守卫

路由独享守卫只适用于特定路由,并在该路由的导航发生时触发。它们通常用于路由特定的任务,例如数据获取和确认操作。

beforeEnter :在进入路由之前触发,并在其组件解析之前。
beforeLeave :在离开路由之前触发,并在其组件销毁之后。

代码示例

以下是使用全局守卫执行身份验证的示例:

import { router } from './router.js';

router.beforeEach((to, from, next) => {
  const isAuthenticated = localStorage.getItem('token');
  if (to.matched.some(record => record.meta.requiresAuth) && !isAuthenticated) {
    // 未登录,导航到登录页面
    next({ name: 'Login' });
  } else {
    // 已登录,继续导航
    next();
  }
});

以下是使用组件内守卫获取数据的示例:

<template>
  <div>
    <h1>{{ user.name }}</h1>
    <button @click="fetchUser()">Get User</button>
  </div>
</template>

<script>
import { beforeRouteEnter } from 'vue-router';

export default {
  data() {
    return {
      user: null,
    };
  },
  beforeRouteEnter(to, from, next) {
    // 获取用户数据
    axios.get('/api/users/' + to.params.id)
      .then(response => {
        this.user = response.data;
        next();
      })
      .catch(error => {
        // 处理错误
        next(error);
      });
  },
  methods: {
    fetchUser() {
      // 重新获取用户数据
      axios.get('/api/users/' + this.$route.params.id)
        .then(response => {
          this.user = response.data;
        })
        .catch(error => {
          // 处理错误
        });
    }
  }
</script>

应用场景

Vue 路由守卫具有广泛的应用场景,包括:

  • 身份验证和授权
  • 数据预取和加载
  • 权限控制
  • 确认操作
  • 记录导航历史
  • 错误处理

总结

Vue 路由守卫是一个功能强大的工具,可以增强 Vue.js 应用程序的灵活性、安全性和用户体验。通过了解不同类型的守卫及其应用场景,开发者可以有效地管理路由导航并构建功能丰富的应用程序。

常见问题解答

1. 不同类型的守卫有什么区别?

全局守卫适用于所有路由,组件内守卫适用于特定组件,路由独享守卫适用于特定路由。

2. 守卫的执行顺序是什么?

全局守卫按注册顺序执行,组件内守卫和路由独享守卫按路由匹配顺序执行。

3. 我可以在守卫中异步获取数据吗?

是的,可以使用 next 函数将守卫解析为 Promise。

4. 我可以阻止导航在守卫中进行吗?

是的,通过将守卫解析为 false 或拒绝的 Promise 即可阻止导航。

5. 如何在守卫中访问路由元信息?

可以使用 to.matched 数组访问路由元信息,其中包含每个匹配路由的元对象。