在 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 项目中的动态目录设置和目录权限控制。这包括了路径别名的配置、动态路由的实现以及权限控制的逻辑。