fix(types): 修正了route的meta类型,新增pageType类型,方便过滤菜单和标签

This commit is contained in:
黄磊 2025-02-27 02:49:33 -05:00
parent 784fa1ef8e
commit 99745ad9fa
15 changed files with 85 additions and 17 deletions

2
.env
View File

@ -17,7 +17,7 @@ VITE_ICON_LOCAL_PREFIX=icon-local
VITE_AUTH_ROUTE_MODE=static VITE_AUTH_ROUTE_MODE=static
# static auth route home # static auth route home
VITE_ROUTE_HOME=home VITE_ROUTE_HOME=pan
# default menu icon # default menu icon
VITE_MENU_ICON=mdi:menu VITE_MENU_ICON=mdi:menu

View File

@ -24,6 +24,10 @@ const inverted = computed(() => !themeStore.darkMode && themeStore.sider.inverte
const expandedKeys = ref<string[]>([]); const expandedKeys = ref<string[]>([]);
const menuOptions = computed(() => {
return routeStore.menus.filter(menu => menu.pageType === routeStore.currentPageType);
});
function updateExpandedKeys() { function updateExpandedKeys() {
if (appStore.siderCollapse || !selectedKey.value) { if (appStore.siderCollapse || !selectedKey.value) {
expandedKeys.value = []; expandedKeys.value = [];
@ -51,7 +55,7 @@ watch(
:collapsed="appStore.siderCollapse" :collapsed="appStore.siderCollapse"
:collapsed-width="themeStore.sider.collapsedWidth" :collapsed-width="themeStore.sider.collapsedWidth"
:collapsed-icon-size="22" :collapsed-icon-size="22"
:options="routeStore.menus" :options="menuOptions"
:inverted="inverted" :inverted="inverted"
:indent="18" :indent="18"
@update:value="routerPushByKeyWithMetaQuery" @update:value="routerPushByKeyWithMetaQuery"

View File

@ -162,7 +162,8 @@ const local: App.I18n.Schema = {
404: 'Page Not Found', 404: 'Page Not Found',
500: 'Server Error', 500: 'Server Error',
'iframe-page': 'Iframe', 'iframe-page': 'Iframe',
home: 'Home' home: 'Home',
pan: 'My Files'
}, },
page: { page: {
login: { login: {

View File

@ -162,7 +162,8 @@ const local: App.I18n.Schema = {
404: '页面不存在', 404: '页面不存在',
500: '服务器错误', 500: '服务器错误',
'iframe-page': '外链页面', 'iframe-page': '外链页面',
home: '首页' home: '首页',
pan: '我的文件'
}, },
page: { page: {
login: { login: {

View File

@ -21,4 +21,5 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"), "iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
login: () => import("@/views/_builtin/login/index.vue"), login: () => import("@/views/_builtin/login/index.vue"),
home: () => import("@/views/home/index.vue"), home: () => import("@/views/home/index.vue"),
pan: () => import("@/views/pan/index.vue"),
}; };

View File

@ -47,7 +47,8 @@ export const generatedRoutes: GeneratedRoute[] = [
title: 'home', title: 'home',
i18nKey: 'route.home', i18nKey: 'route.home',
icon: 'mdi:monitor-dashboard', icon: 'mdi:monitor-dashboard',
order: 1 order: 1,
pageType: 'admin'
} }
}, },
{ {
@ -74,5 +75,15 @@ export const generatedRoutes: GeneratedRoute[] = [
constant: true, constant: true,
hideInMenu: true hideInMenu: true
} }
},
{
name: 'pan',
path: '/pan',
component: 'layout.base$view.pan',
meta: {
title: 'pan',
i18nKey: 'route.pan',
pageType: 'pan'
}
} }
]; ];

View File

@ -168,7 +168,8 @@ const routeMap: RouteMap = {
"500": "/500", "500": "/500",
"home": "/home", "home": "/home",
"iframe-page": "/iframe-page/:url", "iframe-page": "/iframe-page/:url",
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?" "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
"pan": "/pan"
}; };
/** /**

View File

@ -18,6 +18,9 @@ import { localStg } from '@/utils/storage';
*/ */
export function createRouteGuard(router: Router) { export function createRouteGuard(router: Router) {
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
const routeStore = useRouteStore();
// 每次路由变化时更新页面类型
routeStore.setPageType(to);
const location = await initRoute(to); const location = await initRoute(to);
if (location) { if (location) {

View File

@ -1,5 +1,5 @@
import { computed, nextTick, ref, shallowRef } from 'vue'; import { computed, nextTick, ref, shallowRef } from 'vue';
import type { RouteRecordRaw } from 'vue-router'; import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { useBoolean } from '@sa/hooks'; import { useBoolean } from '@sa/hooks';
import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types'; import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
@ -41,6 +41,21 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
/** Home route key */ /** Home route key */
const routeHome = ref(import.meta.env.VITE_ROUTE_HOME); const routeHome = ref(import.meta.env.VITE_ROUTE_HOME);
/** 当前页面的类型 */
const currentPageType = ref<UnionKey.SystemPageType>('pan');
/** 设置当前页面类型方法 */
const setPageType = (route: RouteLocationNormalized) => {
const matched = route.matched;
for (let i = matched.length - 1; i >= 0; i -= 1) {
const type = matched[i].meta?.pageType;
if (type) {
currentPageType.value = type;
return;
}
}
currentPageType.value = 'pan';
};
/** /**
* Set route home * Set route home
* *
@ -343,6 +358,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
getIsAuthRouteExist, getIsAuthRouteExist,
getSelectedMenuKeyPath, getSelectedMenuKeyPath,
onRouteSwitchWhenLoggedIn, onRouteSwitchWhenLoggedIn,
onRouteSwitchWhenNotLoggedIn onRouteSwitchWhenNotLoggedIn,
currentPageType,
setPageType
}; };
}); });

View File

@ -127,19 +127,33 @@ export function updateLocaleOfGlobalMenus(menus: App.Global.Menu[]) {
function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | ElegantConstRoute) { function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | ElegantConstRoute) {
const { SvgIconVNode } = useSvgIcon(); const { SvgIconVNode } = useSvgIcon();
const { name, path } = route; const { name, path, meta } = route;
const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon, iconFontSize } = route.meta ?? {}; const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon, iconFontSize } = route.meta ?? {};
const label = i18nKey ? $t(i18nKey) : title!; const label = i18nKey ? $t(i18nKey) : title!;
const menu: App.Global.Menu = { let menu: App.Global.Menu;
key: name as string,
label, if (meta?.pageType) {
i18nKey, menu = {
routeKey: name as RouteKey, key: name as string,
routePath: path as RouteMap[RouteKey], label,
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 }) i18nKey,
}; routeKey: name as RouteKey,
routePath: path as RouteMap[RouteKey],
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 }),
pageType: meta?.pageType
};
} else {
menu = {
key: name as string,
label,
i18nKey,
routeKey: name as RouteKey,
routePath: path as RouteMap[RouteKey],
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 })
};
}
return menu; return menu;
} }

View File

@ -204,6 +204,7 @@ declare namespace App {
/** The menu icon */ /** The menu icon */
icon?: () => VNode; icon?: () => VNode;
/** The menu children */ /** The menu children */
pageType?: UnionKey.SystemPageType;
children?: Menu[]; children?: Menu[];
}; };

View File

@ -23,6 +23,7 @@ declare module "@elegant-router/types" {
"home": "/home"; "home": "/home";
"iframe-page": "/iframe-page/:url"; "iframe-page": "/iframe-page/:url";
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
"pan": "/pan";
}; };
/** /**
@ -60,6 +61,7 @@ declare module "@elegant-router/types" {
| "home" | "home"
| "iframe-page" | "iframe-page"
| "login" | "login"
| "pan"
>; >;
/** /**
@ -82,6 +84,7 @@ declare module "@elegant-router/types" {
| "iframe-page" | "iframe-page"
| "login" | "login"
| "home" | "home"
| "pan"
>; >;
/** /**

View File

@ -66,6 +66,8 @@ declare module 'vue-router' {
multiTab?: boolean | null; multiTab?: boolean | null;
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
fixedIndexInTab?: number | null; fixedIndexInTab?: number | null;
/** 页面类型 */
pageType?: UnionKey.SystemPageType;
/** if set query parameters, it will be automatically carried when entering the route */ /** if set query parameters, it will be automatically carried when entering the route */
query?: { key: string; value: string }[] | null; query?: { key: string; value: string }[] | null;
} }

View File

@ -51,6 +51,8 @@ declare namespace UnionKey {
*/ */
type ThemeTabMode = import('@sa/materials').PageTabMode; type ThemeTabMode = import('@sa/materials').PageTabMode;
type SystemPageType = 'pan' | 'admin' | null;
/** Unocss animate key */ /** Unocss animate key */
type UnoCssAnimateKey = type UnoCssAnimateKey =
| 'pulse' | 'pulse'

7
src/views/pan/index.vue Normal file
View File

@ -0,0 +1,7 @@
<script setup lang="ts"></script>
<template>
<div>网盘页面</div>
</template>
<style scoped></style>