vue3动态路由的实现以及目录权限的设置

在 Vue 3、TypeScript 和 Vite 项目中,设置动态目录以及目录权限,通常涉及到路径别名的配置、动态路由的实现以及权限控制的逻辑。以下是具体的实现步骤:

1. 动态路由的实现

定义静态路由

在 router/index.ts 中定义静态路由,例如登录页、首页等。

TypeScript 复制代码
import { createRouter, createWebHistory } from 'vue-router';
import Layout from '@/layout/index.vue';

export const constantRoutes = [
  {
    path: '/',
    redirect: '/dashboard',
    hidden: true,
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    meta: {
      title: '首页',
      icon: 'House',
    },
    component: Layout,
  },
  {
    path: '/login',
    name: 'Login',
    meta: {
      title: '登录',
    },
    component: () => import('@/views/user/login/index.vue'),
    hidden: true,
  },
  {
    path: '/:pathMatch(.*)*',
    component: () => import('@/views/error/404.vue'),
    hidden: true,
  },
];

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

export default router;
动态加载路由

创建一个函数来动态加载路由,通常在权限相关的 store 中实现。

TypeScript 复制代码
import { ref } from 'vue';
import router from '@/router';
import type { RouteRecordRaw } from 'vue-router';

const asyncRoutes = ref<RouteRecordRaw[]>([]);

export const useRouterConfig = () => {
  const modules = import.meta.glob('@/views/**');
  const addRoutes = (menus: RouteRecordRaw[]) => {
    asyncRoutes.value = menus;
    filterAsyncRouter();
    router.addRoute({
      path: '/',
      redirect: asyncRoutes.value[0].path,
    });
  };

  const filterAsyncRouter = () => {
    const routerLoop = (routes: RouteRecordRaw[], ParentName?: string) => {
      routes.forEach((item) => {
        if (item.component === 'Layout') {
          item.component = () => import('@/layout/index.vue');
        } else {
          item.component = resolveComponent(item.component);
        }
        const { title, show, icon, name, path, component, children } = item;
        const route: RouteRecordRaw = {
          component,
          path,
          name,
          meta: {
            title,
            show,
            icon,
          },
          children: children as any,
        };

        if (ParentName) {
          router.addRoute(ParentName, route);
        } else {
          router.addRoute(route);
        }

        if (item.children && item.children.length > 0) {
          routerLoop(item.children, item.name);
        }
      });
    };

    routerLoop(asyncRoutes.value);
  };

  const resolveComponent = (path: string) => {
    const importPage = modules[`../views${path}`];
    if (!importPage) {
      throw new Error(`Unknown page ${path}. Is it located under Pages with a .vue extension?`);
    }
    return importPage;
  };

  return { addRoutes };
};

2. 权限控制

在导航守卫中进行权限控制,确保用户只能访问其有权限的路由。

TypeScript 复制代码
import router from './index';
import { useUserStore } from '@/store/user';

const whiteList = ['/login', '/404'];

router.beforeEach(async (to) => {
  const token = localStorage.getItem('token');
  if (whiteList.includes(to.path) && !token) {
    return true;
  } else {
    const { menuList, getMenuList } = useUserStore();
    if (!menuList.length) {
      await getMenuList();
      return { path: to.fullPath };
    }
  }
});

3. 获取后端路由数据

在 store/user.ts 中定义获取用户菜单列表的逻辑。

TypeScript 复制代码
import { defineStore } from 'pinia';
import { ref } from 'vue';

export const useUserStore = defineStore('user', () => {
  const menuList = ref([]);
  const getMenuList = async () => {
    // 这里是获取后端路由数据的 API 调用
    // 模拟获取数据
    menuList.value = [
      {
        path: '/dashboard',
        name: 'Dashboard',
        meta: { title: '首页', icon: 'House' },
        component: 'Layout',
      },
      {
        path: '/user',
        name: 'User',
        meta: { title: '用户管理', icon: 'User' },
        component: 'Layout',
        children: [
          {
            path: '/user/list',
            name: 'UserList',
            meta: { title: '用户列表' },
            component: () => import('@/views/user/list.vue'),
          },
        ],
      },
    ];
  };

  return { menuList, getMenuList };
});

4. 动态路由的初始化

在 main.ts 中初始化动态路由。

TypeScript 复制代码
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import { useRouterConfig } from './router/config';
import { useUserStore } from './store/user';

const app = createApp(App);
app.use(router);

// 初始化动态路由
const { addRoutes } = useRouterConfig();
const userStore = useUserStore();
addRoutes(userStore.menuList);

app.mount('#app');

通过以上步骤可以实现 Vue 3、TypeScript 和 Vite 项目中的动态目录设置和目录权限控制。这包括了路径别名的配置、动态路由的实现以及权限控制的逻辑。

相关推荐
Decay__1 小时前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构
贞明电子3 小时前
工业三色报警灯怎么接入项目系统?开关量与RS485控制应用指南
运维·网络·微信公众平台·贞明电子
HideF4 小时前
Linux
linux·服务器·网络
万联WANFLOW4 小时前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
Ruiery6 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
Decay__7 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
丰锋ff8 小时前
压缩命令笔记
linux
江华森8 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
迪菲赫尔曼8 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
GeW9 小时前
产业新优势基础软件的人才底盘,从Linux与数据库开始
linux·数据库