likes
comments
collection
share

Vue3+TS实现动态路由权限

作者站长头像
站长
· 阅读数 3

当我们在开发一个大型的前端应用时,动态路由权限是一个必不可少的功能。本文将介绍如何使用Vue 3和TypeScript来实现动态路由权限,并且保持性能最佳。

1. 前置知识

在开始之前,你需要对以下知识有基本的了解:

  • Vue 3
  • TypeScript
  • Vue Router

2. 实现思路

动态路由权限的实现思路可以分为以下几个步骤:

  1. 创建一个路由守卫,在进入路由之前判断该路由是否需要进行权限验证。
  2. 在路由配置中添加meta字段来标记该路由需要进行权限验证,以及该路由所需的权限信息。
  3. 创建一个权限验证函数,根据当前用户的角色和路由的权限信息来判断是否有权限访问该路由。
  4. 在权限验证函数中调用后端API获取当前用户的角色信息,并将该信息保存到Vuex状态管理中。
  5. 在路由守卫中调用权限验证函数,并根据验证结果进行相应的操作,例如跳转到登录页或显示无权访问提示。

3. 具体实现

下面将具体介绍如何使用Vue 3和TypeScript来实现动态路由权限。

3.1 创建路由守卫

首先,我们需要创建一个全局路由守卫来判断该路由是否需要进行权限验证。在router/index.ts中添加以下代码:

import { router } from './index';
import store from '../store';

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    const hasToken = store.getters['auth/hasToken'];
    if (!hasToken) {
      // 跳转到登录页
      next('/login');
      return;
    }

    const requiredRoles = to.meta.roles;
    const userRole = store.getters['user/role'];
    if (!requiredRoles.includes(userRole)) {
      // 显示无权访问提示
      next('/403');
      return;
    }
  }

  next();
});

在上面的代码中,我们首先判断该路由是否需要进行权限验证,如果需要,则判断当前用户是否有token,如果没有则跳转到登录页;然后根据当前用户的角色和路由所需的权限信息来判断是否有权限访问该路由,如果没有则显示无权访问提示。

3.2 添加路由元信息

接下来,在路由配置中添加meta字段来标记该路由需要进行权限验证,以及该路由所需的权限信息。在router/index.ts中添加以下代码:

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router';

const routes: RouteRecordRaw[] = [
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/Login.vue'),
  },
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue'),
    meta: {
      requiresAuth: true,
      roles: ['admin', 'editor'],
    },
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('../views/About.vue'),
    meta: {
      requiresAuth: true,
      roles: ['admin'],
    },
  },
  // ...
];

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

在上面的代码中,我们在路由配置中添加了meta字段来定义该路由需要进行权限验证,以及该路由所需的权限信息。

3.3 创建权限验证函数

接下来,我们需要创建一个权限验证函数来判断当前用户是否有权限访问该路由。在store/modules/user.ts中添加以下代码:

import { Module } from 'vuex';
import { RootState } from '../index';

interface UserState {
  id: number;
  role: string;
}

const userModule: Module<UserState, RootState> = {
  namespaced: true,
  state: {
    id: 0,
    role: '',
  },
  getters: {
    role(state): string {
      return state.role;
    },
  },
  mutations: {
    setId(state, id: number) {
      state.id = id;
    },
    setRole(state, role: string) {
      state.role = role;
    },
  },
  actions: {
    async fetchUser({ commit }) {
      // 调用后端API获取当前用户的角色信息
      const response = await fetch('/api/user');
      const data = await response.json();

      commit('setId', data.id);
      commit('setRole', data.role);
    },
  },
};

export default userModule;

export type { UserState };

在上面的代码中,我们首先定义了一个UserState接口来描述用户状态;然后在userModule中定义了一个fetchUser异步action来调用后端API获取当前用户的角色信息,并将该信息保存到Vuex状态管理中。

3.4 调用权限验证函数

最后,在路由守卫中调用权限验证函数,并根据验证结果进行相应的操作。在router/index.ts中添加以下代码:

import { router } from './index';
import store from '../store';

router.beforeEach(async (to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    const hasToken = store.getters['auth/hasToken'];
    if (!hasToken) {
      // 跳转到登录页
      next('/login');
      return;
    }

    const requiredRoles = to.meta.roles;
    const userRole = store.getters['user/role'];

    if (!userRole) {
      // 获取当前用户的角色信息
      await store.dispatch('user/fetchUser');
    }

    if (!requiredRoles.includes(userRole)) {
      // 显示无权访问提示
      next('/403');
      return;
    }
  }

  next();
});

在上面的代码中,我们首先判断该路由是否需要进行权限验证,如果需要,则判断当前用户是否有token,如果没有则跳转到登录页;然后根据当前用户的角色和路由所需的权限信息来判断是否有权限访问该路由,如果没有则显示无权访问提示。在第一次访问需要权限验证的路由时,我们会调用fetchUser异步action来获取当前用户的角色信息,并将该信息保存到Vuex状态管理中。

4. 性能优化

为了保持性能最佳,我们可以使用以下方法对动态路由权限进行优化:

  1. 缓存用户信息:在用户登录后,我们可以将当前用户的角色信息缓存在本地存储或cookie中,以减少不必要的API调用。
  2. 懒加载路由:在路由配置中使用懒加载动态加载路由组件,以减少初始加载时间和减轻页面负担。
  3. 使用路由缓存:在需要进行权限验证的路由组件中使用路由缓存,以减少组件的重复渲染和提高页面响应速度。

5. 总结

以上就是使用Vue 3和TypeScript实现动态路由权限的方法和性能优化。在实际开发中,我们需要根据项目需求和团队约定来进行适当的修改和补充。