mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-25 04:46:37 +08:00
refactor(projects): 优化路由声明,添加路由模块导入,规范路相关文件夹
This commit is contained in:
parent
2fdb5f563f
commit
f199794da0
@ -1,7 +1,7 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
/** 路由描述 */
|
/** 路由描述 */
|
||||||
interface RouteMeta {
|
export interface CustomRouteMeta {
|
||||||
/** 路由名称 */
|
/** 路由名称 */
|
||||||
title?: string;
|
title?: string;
|
||||||
/** 缓存页面 */
|
/** 缓存页面 */
|
||||||
@ -12,12 +12,15 @@ interface RouteMeta {
|
|||||||
isNotMenu?: boolean;
|
isNotMenu?: boolean;
|
||||||
/** 菜单和面包屑对应的图标 */
|
/** 菜单和面包屑对应的图标 */
|
||||||
icon?: string;
|
icon?: string;
|
||||||
/** 路由作为菜单时的排序 */
|
/** 导入的路由模块排序,可用于菜单的排序 */
|
||||||
order?: number;
|
order?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 路由配置 */
|
/** 路由配置 */
|
||||||
export type CustomRoute = RouteRecordRaw & { meta: RouteMeta };
|
export type CustomRoute = RouteRecordRaw & { meta: CustomRouteMeta };
|
||||||
|
|
||||||
|
/** 导入的路由模块 */
|
||||||
|
export type ImportedRouteModules = Record<string, { default: CustomRoute; [key: string]: any }>;
|
||||||
|
|
||||||
/** 路由声明的key */
|
/** 路由声明的key */
|
||||||
export type RouteKey =
|
export type RouteKey =
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
import type { RouteKey } from '@/interface';
|
|
||||||
|
|
||||||
interface RouteConst {
|
|
||||||
/** 路由名称 */
|
|
||||||
name: RouteKey;
|
|
||||||
/** 路由路径 */
|
|
||||||
path: string;
|
|
||||||
/** 路由标题 */
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 声明的路由名称、路径和标题 */
|
|
||||||
const routeConstMap = new Map<RouteKey, RouteConst>([
|
|
||||||
['root', { name: 'root', path: '/', title: 'Root' }],
|
|
||||||
['login', { name: 'login', path: '/login', title: '登录' }],
|
|
||||||
['no-permission', { name: 'no-permission', path: '/403', title: '无权限' }],
|
|
||||||
['not-found', { name: 'not-found', path: '/404', title: '未找到' }],
|
|
||||||
['service-error', { name: 'service-error', path: '/500', title: '服务器错误' }],
|
|
||||||
['dashboard', { name: 'dashboard', path: '/dashboard', title: '仪表盘' }],
|
|
||||||
['dashboard_analysis', { name: 'dashboard_analysis', path: '/dashboard/analysis', title: '分析页' }],
|
|
||||||
['dashboard_workbench', { name: 'dashboard_workbench', path: '/dashboard/workbench', title: '工作台' }],
|
|
||||||
['document', { name: 'document', path: '/document', title: '文档' }],
|
|
||||||
['document_vue', { name: 'document_vue', path: '/document/vue', title: 'vue文档' }],
|
|
||||||
['document_vite', { name: 'document_vite', path: '/document/vite', title: 'vite文档' }],
|
|
||||||
['document_naive', { name: 'document_naive', path: '/document/naive', title: 'naive文档' }],
|
|
||||||
['component', { name: 'component', path: '/component', title: '组件插件' }],
|
|
||||||
['component_map', { name: 'component_map', path: '/component/map', title: '地图插件' }],
|
|
||||||
['component_video', { name: 'component_video', path: '/component/video', title: '视频插件' }],
|
|
||||||
['component_editor', { name: 'component_editor', path: '/component/editor', title: '编辑器' }],
|
|
||||||
[
|
|
||||||
'component_editor_quill',
|
|
||||||
{ name: 'component_editor_quill', path: '/component/editor/quill', title: '富文本编辑器' }
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'component_editor_markdown',
|
|
||||||
{ name: 'component_editor_markdown', path: '/component/editor/markdown', title: 'markdown编辑器' }
|
|
||||||
],
|
|
||||||
['component_swiper', { name: 'component_swiper', path: '/component/swiper', title: 'Swiper插件' }],
|
|
||||||
['feat', { name: 'feat', path: '/feat', title: '功能示例' }],
|
|
||||||
['feat_copy', { name: 'feat_copy', path: '/feat/copy', title: '剪贴板' }],
|
|
||||||
['feat_icon', { name: 'feat_icon', path: '/feat/icon', title: '图标' }],
|
|
||||||
['feat_print', { name: 'feat_print', path: '/feat/print', title: '打印' }],
|
|
||||||
['multi-menu', { name: 'multi-menu', path: '/multi-menu', title: '多级菜单' }],
|
|
||||||
['multi-menu_first', { name: 'multi-menu_first', path: '/multi-menu/first', title: '一级菜单' }],
|
|
||||||
['multi-menu_first_second', { name: 'multi-menu_first_second', path: '/multi-menu/first/second', title: '二级菜单' }],
|
|
||||||
['exception', { name: 'exception', path: '/exception', title: '异常页' }],
|
|
||||||
['exception_403', { name: 'exception_403', path: '/exception/403', title: '异常页-403' }],
|
|
||||||
['exception_404', { name: 'exception_404', path: '/exception/404', title: '异常页-404' }],
|
|
||||||
['exception_500', { name: 'exception_500', path: '/exception/500', title: '异常页-500' }],
|
|
||||||
['about', { name: 'about', path: '/about', title: '关于' }]
|
|
||||||
]);
|
|
||||||
|
|
||||||
/** 获取路由的声明(name、path、title) */
|
|
||||||
export function getRouteConst(key: RouteKey) {
|
|
||||||
return routeConstMap.get(key)!;
|
|
||||||
}
|
|
||||||
/** 路由名称 */
|
|
||||||
export function routeName(key: RouteKey) {
|
|
||||||
return routeConstMap.get(key)!.name;
|
|
||||||
}
|
|
||||||
/** 路由路径 */
|
|
||||||
export function routePath(key: RouteKey) {
|
|
||||||
return routeConstMap.get(key)!.path;
|
|
||||||
}
|
|
||||||
/** 路由标题 */
|
|
||||||
export function routeTitle(key: RouteKey) {
|
|
||||||
return routeConstMap.get(key)!.title;
|
|
||||||
}
|
|
279
src/router/constant/index.ts
Normal file
279
src/router/constant/index.ts
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
import type { RouteKey } from '@/interface';
|
||||||
|
|
||||||
|
interface RouteConst {
|
||||||
|
/** 路由名称 */
|
||||||
|
name: RouteKey;
|
||||||
|
/** 路由路径 */
|
||||||
|
path: string;
|
||||||
|
/** 路由标题 */
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 声明的路由名称、路径和标题 */
|
||||||
|
const routeConstMap = new Map<RouteKey, RouteConst>([
|
||||||
|
[
|
||||||
|
'root',
|
||||||
|
{
|
||||||
|
name: 'root',
|
||||||
|
path: '/',
|
||||||
|
title: 'Root'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'login',
|
||||||
|
{
|
||||||
|
name: 'login',
|
||||||
|
path: '/login',
|
||||||
|
title: '登录'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'no-permission',
|
||||||
|
{
|
||||||
|
name: 'no-permission',
|
||||||
|
path: '/403',
|
||||||
|
title: '无权限'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'not-found',
|
||||||
|
{
|
||||||
|
name: 'not-found',
|
||||||
|
path: '/404',
|
||||||
|
title: '未找到'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'service-error',
|
||||||
|
{
|
||||||
|
name: 'service-error',
|
||||||
|
path: '/500',
|
||||||
|
title: '服务器错误'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'dashboard',
|
||||||
|
{
|
||||||
|
name: 'dashboard',
|
||||||
|
path: '/dashboard',
|
||||||
|
title: '仪表盘'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'dashboard_analysis',
|
||||||
|
{
|
||||||
|
name: 'dashboard_analysis',
|
||||||
|
path: '/dashboard/analysis',
|
||||||
|
title: '分析页'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'dashboard_workbench',
|
||||||
|
{
|
||||||
|
name: 'dashboard_workbench',
|
||||||
|
path: '/dashboard/workbench',
|
||||||
|
title: '工作台'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'document',
|
||||||
|
{
|
||||||
|
name: 'document',
|
||||||
|
path: '/document',
|
||||||
|
title: '文档'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'document_vue',
|
||||||
|
{
|
||||||
|
name: 'document_vue',
|
||||||
|
path: '/document/vue',
|
||||||
|
title: 'vue文档'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'document_vite',
|
||||||
|
{
|
||||||
|
name: 'document_vite',
|
||||||
|
path: '/document/vite',
|
||||||
|
title: 'vite文档'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'document_naive',
|
||||||
|
{
|
||||||
|
name: 'document_naive',
|
||||||
|
path: '/document/naive',
|
||||||
|
title: 'naive文档'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component',
|
||||||
|
{
|
||||||
|
name: 'component',
|
||||||
|
path: '/component',
|
||||||
|
title: '组件插件'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_map',
|
||||||
|
{
|
||||||
|
name: 'component_map',
|
||||||
|
path: '/component/map',
|
||||||
|
title: '地图插件'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_video',
|
||||||
|
{
|
||||||
|
name: 'component_video',
|
||||||
|
path: '/component/video',
|
||||||
|
title: '视频插件'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_editor',
|
||||||
|
{
|
||||||
|
name: 'component_editor',
|
||||||
|
path: '/component/editor',
|
||||||
|
title: '编辑器'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_editor_quill',
|
||||||
|
{
|
||||||
|
name: 'component_editor_quill',
|
||||||
|
path: '/component/editor/quill',
|
||||||
|
title: '富文本编辑器'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_editor_markdown',
|
||||||
|
{
|
||||||
|
name: 'component_editor_markdown',
|
||||||
|
path: '/component/editor/markdown',
|
||||||
|
title: 'markdown编辑器'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'component_swiper',
|
||||||
|
{
|
||||||
|
name: 'component_swiper',
|
||||||
|
path: '/component/swiper',
|
||||||
|
title: 'Swiper插件'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'feat',
|
||||||
|
{
|
||||||
|
name: 'feat',
|
||||||
|
path: '/feat',
|
||||||
|
title: '功能示例'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'feat_copy',
|
||||||
|
{
|
||||||
|
name: 'feat_copy',
|
||||||
|
path: '/feat/copy',
|
||||||
|
title: '剪贴板'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'feat_icon',
|
||||||
|
{
|
||||||
|
name: 'feat_icon',
|
||||||
|
path: '/feat/icon',
|
||||||
|
title: '图标'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'feat_print',
|
||||||
|
{
|
||||||
|
name: 'feat_print',
|
||||||
|
path: '/feat/print',
|
||||||
|
title: '打印'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'multi-menu',
|
||||||
|
{
|
||||||
|
name: 'multi-menu',
|
||||||
|
path: '/multi-menu',
|
||||||
|
title: '多级菜单'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'multi-menu_first',
|
||||||
|
{
|
||||||
|
name: 'multi-menu_first',
|
||||||
|
path: '/multi-menu/first',
|
||||||
|
title: '一级菜单'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'multi-menu_first_second',
|
||||||
|
{
|
||||||
|
name: 'multi-menu_first_second',
|
||||||
|
path: '/multi-menu/first/second',
|
||||||
|
title: '二级菜单'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'exception',
|
||||||
|
{
|
||||||
|
name: 'exception',
|
||||||
|
path: '/exception',
|
||||||
|
title: '异常页'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'exception_403',
|
||||||
|
{
|
||||||
|
name: 'exception_403',
|
||||||
|
path: '/exception/403',
|
||||||
|
title: '异常页-403'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'exception_404',
|
||||||
|
{
|
||||||
|
name: 'exception_404',
|
||||||
|
path: '/exception/404',
|
||||||
|
title: '异常页-404'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'exception_500',
|
||||||
|
{
|
||||||
|
name: 'exception_500',
|
||||||
|
path: '/exception/500',
|
||||||
|
title: '异常页-500'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'about',
|
||||||
|
{
|
||||||
|
name: 'about',
|
||||||
|
path: '/about',
|
||||||
|
title: '关于'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
/** 获取路由的声明(name、path、title) */
|
||||||
|
export function getRouteConst(key: RouteKey) {
|
||||||
|
return routeConstMap.get(key)!;
|
||||||
|
}
|
||||||
|
/** 路由名称 */
|
||||||
|
export function routeName(key: RouteKey) {
|
||||||
|
return routeConstMap.get(key)!.name;
|
||||||
|
}
|
||||||
|
/** 路由路径 */
|
||||||
|
export function routePath(key: RouteKey) {
|
||||||
|
return routeConstMap.get(key)!.path;
|
||||||
|
}
|
||||||
|
/** 路由标题 */
|
||||||
|
export function routeTitle(key: RouteKey) {
|
||||||
|
return routeConstMap.get(key)!.title;
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import type { RouteLocationNormalized, NavigationGuardNext } from 'vue-router';
|
import type { RouteLocationNormalized, NavigationGuardNext } from 'vue-router';
|
||||||
import { routeName } from '@/router';
|
import { router, routeName } from '@/router';
|
||||||
import { getToken, getLoginRedirectUrl } from '@/utils';
|
import { getToken, getLoginRedirectUrl } from '@/utils';
|
||||||
|
|
||||||
type RouterAction = [boolean, () => void];
|
type RouterAction = [boolean, () => void];
|
||||||
@ -33,7 +33,7 @@ export function handlePagePermission(
|
|||||||
[
|
[
|
||||||
!isLogin && needLogin,
|
!isLogin && needLogin,
|
||||||
() => {
|
() => {
|
||||||
const redirectUrl = getLoginRedirectUrl();
|
const redirectUrl = getLoginRedirectUrl(router);
|
||||||
next({ name: routeName('login'), query: { redirectUrl } });
|
next({ name: routeName('login'), query: { redirectUrl } });
|
||||||
}
|
}
|
||||||
],
|
],
|
@ -1,3 +1,3 @@
|
|||||||
export * from './const';
|
export * from './constant';
|
||||||
export * from './routes';
|
export * from './routes';
|
||||||
export * from './setup';
|
export * from './setup';
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { setRouterCacheName, setSingleRoute } from '@/utils';
|
import { setSingleRoute } from '@/utils';
|
||||||
import { BasicLayout } from '@/layouts';
|
import { BasicLayout } from '@/layouts';
|
||||||
import About from '@/views/about/index.vue';
|
import About from '@/views/about/index.vue';
|
||||||
import { getRouteConst } from '../const';
|
import { getRouteConst, routeName } from '../constant';
|
||||||
|
|
||||||
const { name, path, title } = getRouteConst('about');
|
const { name, path, title } = getRouteConst('about');
|
||||||
setRouterCacheName(About, name);
|
|
||||||
|
|
||||||
const ABOUT: CustomRoute = setSingleRoute(BasicLayout, {
|
const ABOUT: CustomRoute = setSingleRoute({
|
||||||
|
route: {
|
||||||
name,
|
name,
|
||||||
path,
|
path,
|
||||||
component: About,
|
component: About,
|
||||||
@ -16,6 +16,12 @@ const ABOUT: CustomRoute = setSingleRoute(BasicLayout, {
|
|||||||
title,
|
title,
|
||||||
icon: 'fluent:book-information-24-regular'
|
icon: 'fluent:book-information-24-regular'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
container: BasicLayout,
|
||||||
|
meta: {
|
||||||
|
order: 7
|
||||||
|
},
|
||||||
|
notFoundName: routeName('not-found')
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ABOUT;
|
export default ABOUT;
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout, RouterViewLayout } from '@/layouts';
|
import { BasicLayout, RouterViewLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import ComponentMap from '@/views/component/map/index.vue';
|
import ComponentMap from '@/views/component/map/index.vue';
|
||||||
import ComponentVideo from '@/views/component/video/index.vue';
|
import ComponentVideo from '@/views/component/video/index.vue';
|
||||||
import EditorQuill from '@/views/component/editor/quill/index.vue';
|
import EditorQuill from '@/views/component/editor/quill/index.vue';
|
||||||
import EditorMarkdown from '@/views/component/editor/markdown/index.vue';
|
import EditorMarkdown from '@/views/component/editor/markdown/index.vue';
|
||||||
import ComponentSwiper from '@/views/component/swiper/index.vue';
|
import ComponentSwiper from '@/views/component/swiper/index.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
|
||||||
setRouterCacheName(ComponentMap, routeName('component_map'));
|
|
||||||
setRouterCacheName(ComponentVideo, routeName('component_video'));
|
|
||||||
setRouterCacheName(EditorQuill, routeName('component_editor_quill'));
|
|
||||||
setRouterCacheName(EditorMarkdown, routeName('component_editor_markdown'));
|
|
||||||
setRouterCacheName(ComponentSwiper, routeName('component_swiper'));
|
|
||||||
|
|
||||||
const COMPONENT: CustomRoute = {
|
const COMPONENT: CustomRoute = {
|
||||||
name: routeName('component'),
|
name: routeName('component'),
|
||||||
@ -22,7 +15,8 @@ const COMPONENT: CustomRoute = {
|
|||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
title: routeTitle('component'),
|
title: routeTitle('component'),
|
||||||
icon: 'fluent:app-store-24-regular'
|
icon: 'fluent:app-store-24-regular',
|
||||||
|
order: 3
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout } from '@/layouts';
|
import { BasicLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
import DashboardAnalysis from '@/views/dashboard/analysis/index.vue';
|
||||||
import DashboardWorkbench from '@/views/dashboard/workbench/index.vue';
|
import DashboardWorkbench from '@/views/dashboard/workbench/index.vue';
|
||||||
import { ROUTE_HOME } from '../routes';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
|
||||||
|
|
||||||
setRouterCacheName(DashboardWorkbench, routeName('dashboard_workbench'));
|
|
||||||
|
|
||||||
const DASHBOARD: CustomRoute = {
|
const DASHBOARD: CustomRoute = {
|
||||||
name: routeName('dashboard'),
|
name: routeName('dashboard'),
|
||||||
@ -14,10 +11,20 @@ const DASHBOARD: CustomRoute = {
|
|||||||
redirect: { name: routeName('dashboard_analysis') },
|
redirect: { name: routeName('dashboard_analysis') },
|
||||||
meta: {
|
meta: {
|
||||||
title: routeTitle('dashboard'),
|
title: routeTitle('dashboard'),
|
||||||
icon: 'carbon:dashboard'
|
icon: 'carbon:dashboard',
|
||||||
|
order: 1
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
ROUTE_HOME,
|
{
|
||||||
|
name: routeName('dashboard_analysis'),
|
||||||
|
path: routePath('dashboard_analysis'),
|
||||||
|
component: DashboardAnalysis,
|
||||||
|
meta: {
|
||||||
|
keepAlive: true,
|
||||||
|
requiresAuth: true,
|
||||||
|
title: routeTitle('dashboard_analysis')
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: routeName('dashboard_workbench'),
|
name: routeName('dashboard_workbench'),
|
||||||
path: routePath('dashboard_workbench'),
|
path: routePath('dashboard_workbench'),
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout } from '@/layouts';
|
import { BasicLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import DocumentVue from '@/views/document/vue/index.vue';
|
import DocumentVue from '@/views/document/vue/index.vue';
|
||||||
import DocumentVite from '@/views/document/vite/index.vue';
|
import DocumentVite from '@/views/document/vite/index.vue';
|
||||||
import DocumentNaive from '@/views/document/naive/index.vue';
|
import DocumentNaive from '@/views/document/naive/index.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
|
||||||
setRouterCacheName(DocumentVue, routeName('document_vue'));
|
|
||||||
setRouterCacheName(DocumentVite, routeName('document_vite'));
|
|
||||||
setRouterCacheName(DocumentNaive, routeName('document_naive'));
|
|
||||||
|
|
||||||
const DOCUMENT: CustomRoute = {
|
const DOCUMENT: CustomRoute = {
|
||||||
name: routeName('document'),
|
name: routeName('document'),
|
||||||
@ -18,7 +13,8 @@ const DOCUMENT: CustomRoute = {
|
|||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
title: routeTitle('document'),
|
title: routeTitle('document'),
|
||||||
icon: 'carbon:document'
|
icon: 'carbon:document',
|
||||||
|
order: 2
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout } from '@/layouts';
|
import { BasicLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import Exception403 from '@/views/system/exception/403.vue';
|
import Exception403 from '@/views/system/exception/403.vue';
|
||||||
import Exception404 from '@/views/system/exception/404.vue';
|
import Exception404 from '@/views/system/exception/404.vue';
|
||||||
import Exception500 from '@/views/system/exception/500.vue';
|
import Exception500 from '@/views/system/exception/500.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
|
||||||
setRouterCacheName(Exception404, routeName('exception_404'));
|
|
||||||
setRouterCacheName(Exception403, routeName('exception_403'));
|
|
||||||
setRouterCacheName(Exception500, routeName('exception_500'));
|
|
||||||
|
|
||||||
const EXCEPTION: CustomRoute = {
|
const EXCEPTION: CustomRoute = {
|
||||||
name: routeName('exception'),
|
name: routeName('exception'),
|
||||||
@ -18,7 +13,8 @@ const EXCEPTION: CustomRoute = {
|
|||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
title: routeTitle('exception'),
|
title: routeTitle('exception'),
|
||||||
icon: 'ant-design:exception-outlined'
|
icon: 'ant-design:exception-outlined',
|
||||||
|
order: 5
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -1,14 +1,9 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout } from '@/layouts';
|
import { BasicLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import FeatCopy from '@/views/feat/copy/index.vue';
|
import FeatCopy from '@/views/feat/copy/index.vue';
|
||||||
import FeatIcon from '@/views/feat/icon/index.vue';
|
import FeatIcon from '@/views/feat/icon/index.vue';
|
||||||
import FeatPrint from '@/views/feat/print/index.vue';
|
import FeatPrint from '@/views/feat/print/index.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
|
||||||
setRouterCacheName(FeatCopy, routeName('feat_copy'));
|
|
||||||
setRouterCacheName(FeatIcon, routeName('feat_icon'));
|
|
||||||
setRouterCacheName(FeatPrint, routeName('feat_print'));
|
|
||||||
|
|
||||||
const FEAT: CustomRoute = {
|
const FEAT: CustomRoute = {
|
||||||
name: routeName('feat'),
|
name: routeName('feat'),
|
||||||
@ -18,7 +13,8 @@ const FEAT: CustomRoute = {
|
|||||||
meta: {
|
meta: {
|
||||||
requiresAuth: true,
|
requiresAuth: true,
|
||||||
title: routeTitle('feat'),
|
title: routeTitle('feat'),
|
||||||
icon: 'ic:round-repeat'
|
icon: 'ic:round-repeat',
|
||||||
|
order: 4
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
import ROOT from './root';
|
import { transformRouteModules } from '@/utils';
|
||||||
import DASHBOARD from './dashboard';
|
import type { ImportedRouteModules } from '@/interface';
|
||||||
import DOCUMENT from './document';
|
|
||||||
import COMPONENT from './component';
|
|
||||||
import FEAT from './feat';
|
|
||||||
import EXCEPTION from './exception';
|
|
||||||
import MULTI_MENU from './multi-menu';
|
|
||||||
import ABOUT from './about';
|
|
||||||
|
|
||||||
export default [ROOT, DASHBOARD, DOCUMENT, COMPONENT, FEAT, EXCEPTION, MULTI_MENU, ABOUT];
|
const modules = import.meta.globEager('./*.ts') as ImportedRouteModules;
|
||||||
|
|
||||||
|
const customRoutes = transformRouteModules(modules);
|
||||||
|
|
||||||
|
export default customRoutes;
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
import type { CustomRoute } from '@/interface';
|
||||||
import { BasicLayout, RouterViewLayout } from '@/layouts';
|
import { BasicLayout, RouterViewLayout } from '@/layouts';
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import MultiMenuFirstSecond from '@/views/multi-menu/first/second/index.vue';
|
import MultiMenuFirstSecond from '@/views/multi-menu/first/second/index.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
|
||||||
setRouterCacheName(MultiMenuFirstSecond, routeName('multi-menu_first_second'));
|
|
||||||
|
|
||||||
const MULTI_MENU: CustomRoute = {
|
const MULTI_MENU: CustomRoute = {
|
||||||
name: routeName('multi-menu'),
|
name: routeName('multi-menu'),
|
||||||
@ -13,7 +10,8 @@ const MULTI_MENU: CustomRoute = {
|
|||||||
redirect: { name: routeName('multi-menu_first') },
|
redirect: { name: routeName('multi-menu_first') },
|
||||||
meta: {
|
meta: {
|
||||||
title: routeTitle('multi-menu'),
|
title: routeTitle('multi-menu'),
|
||||||
icon: 'carbon:menu'
|
icon: 'carbon:menu',
|
||||||
|
order: 6
|
||||||
},
|
},
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
|
||||||
import { routeName, routePath } from '../const';
|
|
||||||
import { ROUTE_HOME } from '../routes';
|
|
||||||
|
|
||||||
const ROOT: CustomRoute = {
|
|
||||||
name: routeName('root'),
|
|
||||||
path: routePath('root'),
|
|
||||||
redirect: { name: ROUTE_HOME.name },
|
|
||||||
meta: {
|
|
||||||
isNotMenu: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ROOT;
|
|
@ -5,7 +5,8 @@ import Login from '@/views/system/login/index.vue';
|
|||||||
import NoPermission from '@/views/system/exception/403.vue';
|
import NoPermission from '@/views/system/exception/403.vue';
|
||||||
import NotFound from '@/views/system/exception/404.vue';
|
import NotFound from '@/views/system/exception/404.vue';
|
||||||
import ServiceError from '@/views/system/exception/500.vue';
|
import ServiceError from '@/views/system/exception/500.vue';
|
||||||
import { routeName, routePath, routeTitle } from '../const';
|
import { routeName, routePath, routeTitle } from '../constant';
|
||||||
|
import { ROUTE_HOME_NAME } from './route-home';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 固定不变的路由
|
* 固定不变的路由
|
||||||
@ -13,8 +14,14 @@ import { routeName, routePath, routeTitle } from '../const';
|
|||||||
*/
|
*/
|
||||||
const constantRoutes: RouteRecordRaw[] = [
|
const constantRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
name: 'single_',
|
name: routeName('root'),
|
||||||
path: '/single_',
|
path: routePath('root'),
|
||||||
|
redirect: { name: ROUTE_HOME_NAME }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 名称、路由随意,不在路由声明里面,只是为各个页面充当传递BlankLayout的桥梁,因此访问该路由时重定向到404
|
||||||
|
name: 'constant-single_',
|
||||||
|
path: '/constant-single_',
|
||||||
component: BlankLayout,
|
component: BlankLayout,
|
||||||
redirect: { name: routeName('not-found') },
|
redirect: { name: routeName('not-found') },
|
||||||
meta: {
|
meta: {
|
@ -1,9 +1,8 @@
|
|||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
import ROUTE_HOME from './routeHome';
|
|
||||||
import customRoutes from '../modules';
|
import customRoutes from '../modules';
|
||||||
import constantRoutes from './constant';
|
import constantRoutes from './constant-routes';
|
||||||
|
|
||||||
/** 所有路由 */
|
/** 所有路由 */
|
||||||
export const routes: RouteRecordRaw[] = [...customRoutes, ...constantRoutes];
|
export const routes: RouteRecordRaw[] = [...customRoutes, ...constantRoutes];
|
||||||
|
|
||||||
export { ROUTE_HOME, customRoutes };
|
export { ROUTE_HOME } from './route-home';
|
||||||
|
9
src/router/routes/route-home.ts
Normal file
9
src/router/routes/route-home.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { getRouteHome } from '@/utils';
|
||||||
|
import { routeName } from '../constant';
|
||||||
|
import customRoutes from '../modules';
|
||||||
|
|
||||||
|
/** 路由首页的名字 */
|
||||||
|
export const ROUTE_HOME_NAME = routeName('dashboard_analysis');
|
||||||
|
|
||||||
|
/** 路由首页 */
|
||||||
|
export const ROUTE_HOME = getRouteHome(customRoutes, ROUTE_HOME_NAME);
|
@ -1,21 +0,0 @@
|
|||||||
import type { CustomRoute } from '@/interface';
|
|
||||||
import { setRouterCacheName } from '@/utils';
|
|
||||||
import DashboardAnalysis from '@/views/dashboard/analysis/index.vue';
|
|
||||||
import { getRouteConst } from '../const';
|
|
||||||
|
|
||||||
const { name, path, title } = getRouteConst('dashboard_analysis');
|
|
||||||
|
|
||||||
setRouterCacheName(DashboardAnalysis, name);
|
|
||||||
|
|
||||||
/** 路由首页 */
|
|
||||||
const ROUTE_HOME: CustomRoute = {
|
|
||||||
name,
|
|
||||||
path,
|
|
||||||
component: DashboardAnalysis,
|
|
||||||
meta: {
|
|
||||||
requiresAuth: true,
|
|
||||||
title
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ROUTE_HOME;
|
|
7
src/router/setup/cache.ts
Normal file
7
src/router/setup/cache.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { getCacheRoutes } from '@/utils';
|
||||||
|
import { routes } from '../routes';
|
||||||
|
|
||||||
|
/** 缓存的路由对应vue页面的名称 */
|
||||||
|
const cacheRoutes = getCacheRoutes(routes);
|
||||||
|
|
||||||
|
export default cacheRoutes;
|
@ -1,8 +1,7 @@
|
|||||||
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
|
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { getCacheRoutes, transformRouteToMenu } from '@/utils';
|
import { routes } from '../routes';
|
||||||
import { routes, customRoutes } from '../routes';
|
import { createRouterGuide } from '../guard';
|
||||||
import { createRouterGuide } from '../guide';
|
|
||||||
|
|
||||||
/** 用于部署vercel托管服务 */
|
/** 用于部署vercel托管服务 */
|
||||||
const isStaging = import.meta.env.VITE_HTTP_ENV === 'STAGING';
|
const isStaging = import.meta.env.VITE_HTTP_ENV === 'STAGING';
|
||||||
@ -18,8 +17,5 @@ export async function setupRouter(app: App) {
|
|||||||
await router.isReady();
|
await router.isReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 缓存的路由对应vue页面的名称 */
|
export { default as cacheRoutes } from './cache';
|
||||||
export const cacheRoutes = getCacheRoutes(routes);
|
export { default as menus } from './menus';
|
||||||
|
|
||||||
/** 菜单 */
|
|
||||||
export const menus = transformRouteToMenu(customRoutes);
|
|
||||||
|
7
src/router/setup/menus.ts
Normal file
7
src/router/setup/menus.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { transformRouteToMenu } from '@/utils';
|
||||||
|
import customRoutes from '../modules';
|
||||||
|
|
||||||
|
/** 菜单 */
|
||||||
|
const menus = transformRouteToMenu(customRoutes);
|
||||||
|
|
||||||
|
export default menus;
|
@ -1,3 +1,4 @@
|
|||||||
|
import type { Component } from 'vue';
|
||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
function getCacheName(route: RouteRecordRaw, isCache: boolean) {
|
function getCacheName(route: RouteRecordRaw, isCache: boolean) {
|
||||||
@ -5,6 +6,7 @@ function getCacheName(route: RouteRecordRaw, isCache: boolean) {
|
|||||||
const hasChild = hasChildren(route);
|
const hasChild = hasChildren(route);
|
||||||
if (isCache && !hasChild) {
|
if (isCache && !hasChild) {
|
||||||
const name = route.name as string;
|
const name = route.name as string;
|
||||||
|
setComponentName(route.component, name);
|
||||||
cacheNames.push(name);
|
cacheNames.push(name);
|
||||||
}
|
}
|
||||||
if (hasChild) {
|
if (hasChild) {
|
||||||
@ -24,6 +26,13 @@ function hasChildren(route: RouteRecordRaw) {
|
|||||||
return Boolean(route.children && route.children.length);
|
return Boolean(route.children && route.children.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 给需要缓存的页面组件设置名称 */
|
||||||
|
export function setComponentName(component?: Component, name?: string) {
|
||||||
|
if (component && name) {
|
||||||
|
Object.assign(component, { name });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 获取被缓存的路由 */
|
/** 获取被缓存的路由 */
|
||||||
export function getCacheRoutes(routes: RouteRecordRaw[]) {
|
export function getCacheRoutes(routes: RouteRecordRaw[]) {
|
||||||
const cacheNames: string[] = [];
|
const cacheNames: string[] = [];
|
||||||
|
@ -1,34 +1,74 @@
|
|||||||
import type { Component } from 'vue';
|
import type { Component } from 'vue';
|
||||||
import type { CustomRoute } from '@/interface';
|
import type { Router } from 'vue-router';
|
||||||
import { router } from '@/router';
|
import type { CustomRoute, ImportedRouteModules, CustomRouteMeta } from '@/interface';
|
||||||
|
|
||||||
/** 给需要缓存的页面组件设置名称 */
|
/** 处理导入的路由模块 */
|
||||||
export function setRouterCacheName(component: Component, name?: string) {
|
export function transformRouteModules(routeModules: ImportedRouteModules) {
|
||||||
if (name) {
|
const modules = Object.keys(routeModules).map(key => {
|
||||||
Object.assign(component, { name });
|
return routeModules[key].default;
|
||||||
|
});
|
||||||
|
const constantRoutes: CustomRoute[] = modules.sort((next, pre) => Number(next.meta.order) - Number(pre.meta.order));
|
||||||
|
return constantRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取路由的首页
|
||||||
|
* @param routes - 路由
|
||||||
|
* @param routeHomeName - 路由首页名称
|
||||||
|
*/
|
||||||
|
export function getRouteHome(routes: CustomRoute[], routeHomeName: string) {
|
||||||
|
let routeHome: CustomRoute;
|
||||||
|
function hasChildren(route: CustomRoute) {
|
||||||
|
return Boolean(route.children && route.children.length);
|
||||||
}
|
}
|
||||||
|
function getRouteHomeByRoute(route: CustomRoute) {
|
||||||
|
if (routeHome) return;
|
||||||
|
const hasChild = hasChildren(route);
|
||||||
|
if (!hasChild) {
|
||||||
|
if (route.name === routeHomeName) {
|
||||||
|
routeHome = route;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getRouteHomeByRoutes(route.children as CustomRoute[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function getRouteHomeByRoutes(_routes: CustomRoute[]) {
|
||||||
|
_routes.some(item => {
|
||||||
|
getRouteHomeByRoute(item as CustomRoute);
|
||||||
|
return routeHome !== undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getRouteHomeByRoutes(routes);
|
||||||
|
return routeHome!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 获取登录后的重定向地址 */
|
/** 获取登录后的重定向地址 */
|
||||||
export function getLoginRedirectUrl() {
|
export function getLoginRedirectUrl(router: Router) {
|
||||||
const path = router.currentRoute.value.fullPath as string;
|
const path = router.currentRoute.value.fullPath as string;
|
||||||
const redirectUrl = path === '/' ? undefined : path;
|
const redirectUrl = path === '/' ? undefined : path;
|
||||||
return redirectUrl;
|
return redirectUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
interface SingleRouteConfig {
|
||||||
* 设置单个路由
|
/** 路由 */
|
||||||
* @param route - 路由
|
route: CustomRoute;
|
||||||
* @param notFoundName - 404未找到的路由名称
|
/** 路由容器 */
|
||||||
* @param container - 路由容器
|
container: Component;
|
||||||
*/
|
/** 路由容器的描述 */
|
||||||
export function setSingleRoute(container: Component, route: CustomRoute, notFoundName = 'not-found') {
|
meta: CustomRouteMeta;
|
||||||
|
/** 404路由的名称 */
|
||||||
|
notFoundName: string;
|
||||||
|
}
|
||||||
|
/** * 设置单个路由 */
|
||||||
|
export function setSingleRoute(config: SingleRouteConfig) {
|
||||||
|
const { route, container, meta, notFoundName } = config;
|
||||||
const routeItem: CustomRoute = {
|
const routeItem: CustomRoute = {
|
||||||
name: `${route.name as string}_`,
|
name: `${route.name as string}_`,
|
||||||
path: `${route.path}_`,
|
path: `${route.path}_`,
|
||||||
component: container,
|
component: container,
|
||||||
redirect: { name: notFoundName },
|
redirect: { name: notFoundName },
|
||||||
meta: {
|
meta: {
|
||||||
|
...meta,
|
||||||
isNotMenu: true
|
isNotMenu: true
|
||||||
},
|
},
|
||||||
children: [route]
|
children: [route]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import type { CustomRoute, GlobalMenuOption } from '@/interface';
|
import type { CustomRoute, GlobalMenuOption } from '@/interface';
|
||||||
import { iconifyRender } from '@/utils';
|
import { iconifyRender } from '../common';
|
||||||
|
|
||||||
/** 判断路由是否作为菜单 */
|
/** 判断路由是否作为菜单 */
|
||||||
function asMenu(route: CustomRoute) {
|
function asMenu(route: CustomRoute) {
|
||||||
|
Loading…
Reference in New Issue
Block a user