fix(projects): 修复面包屑数据

This commit is contained in:
Soybean
2022-01-14 14:17:34 +08:00
parent 839b82ba8b
commit 28b5d22401
6 changed files with 193 additions and 132 deletions

View File

@ -1,34 +1,69 @@
import { watch, onUnmounted } from 'vue';
import { computed, watch, onUnmounted } from 'vue';
import type { ComputedRef } from 'vue';
import useBoolean from './useBoolean';
interface ScrollBodyStyle {
overflow: string;
paddingRight: string;
}
/**
* 使用弹窗
* @param hide - 关闭html滚动条
* @param hideScroll - 关闭html滚动条
* @param duration - 显示滚动条的延迟时间
*/
export default function useModalVisible(hideScroll = true) {
export default function useModalVisible(hideScroll = true, duration = 300) {
const { bool: visible, setTrue: openModal, setFalse: closeModal, toggle: toggleModal } = useBoolean();
const stopHandle = watch(visible, async newValue => {
const defaultStyle: ScrollBodyStyle = {
overflow: '',
paddingRight: ''
};
function getInitBodyStyle() {
if (hideScroll) {
const className = 'overflow-hidden';
if (newValue) {
document.body.classList.add(className);
} else {
setTimeout(() => {
document.body.classList.remove(className);
}, 300);
}
const { overflow, paddingRight } = document.body.style;
Object.assign(defaultStyle, { overflow, paddingRight });
}
});
}
function setScrollBodyStyle() {
document.body.style.paddingRight = `${window.innerWidth - document.body.clientWidth}px`;
document.body.style.overflow = 'hidden';
}
function resetScrollBodyStyle() {
document.body.style.overflow = defaultStyle.overflow;
document.body.style.paddingRight = defaultStyle.paddingRight;
}
onUnmounted(() => {
stopHandle();
});
function modalVisibleWatcher(visible: ComputedRef<boolean>) {
const stopHandle = watch(visible, async newValue => {
if (hideScroll) {
if (newValue) {
setScrollBodyStyle();
} else {
setTimeout(() => {
resetScrollBodyStyle();
}, duration);
}
}
});
onUnmounted(() => {
stopHandle();
});
}
function init() {
getInitBodyStyle();
modalVisibleWatcher(computed(() => visible.value));
}
init();
return {
visible,
openModal,
closeModal,
toggleModal
toggleModal,
modalVisibleWatcher
};
}

View File

@ -13,6 +13,5 @@ export type GlobalBreadcrumb = DropdownOption & {
disabled: boolean;
routeName: string;
hasChildren: boolean;
iconName?: string;
children?: GlobalBreadcrumb[];
};

View File

@ -9,10 +9,6 @@ import type { GlobalMenuOption } from '@/interface';
/** 路由状态 */
interface RouteStore {
/** 动态路由 */
routes: Ref<AuthRoute.Route[]>;
/** 设置动态路由数据 */
setRoutes(data: AuthRoute.Route[]): void;
/** 是否添加过动态路由 */
isAddedDynamicRoute: Ref<boolean>;
/** 初始化动态路由 */
@ -22,11 +18,6 @@ interface RouteStore {
}
export const useRouteStore = defineStore('route-store', () => {
const routes = ref<AuthRoute.Route[]>([]);
function setRoutes(data: AuthRoute.Route[]) {
routes.value = data;
}
const menus = ref<GlobalMenuOption[]>([]) as Ref<GlobalMenuOption[]>;
function getMenus(data: AuthRoute.Route[]) {
const transform = transformAuthRouteToMenu(data);
@ -49,8 +40,6 @@ export const useRouteStore = defineStore('route-store', () => {
}
const routeStore: RouteStore = {
routes,
setRoutes,
isAddedDynamicRoute,
initDynamicRoute,
menus

View File

@ -7,29 +7,67 @@ import type { GlobalMenuOption, GlobalBreadcrumb } from '@/interface';
* @param rootPath - 根路由路径
*/
export function getBreadcrumbByRouteKey(activeKey: string, menus: GlobalMenuOption[], rootPath: string) {
return menus.map(menu => getBreadcrumbItem(activeKey, menu, rootPath)).flat(1);
const breadcrumbMenu = getBreadcrumbMenu(activeKey, menus);
const breadcrumb = breadcrumbMenu.map(item => transformBreadcrumbMenuToBreadcrumb(item, rootPath));
return breadcrumb;
}
function getBreadcrumbItem(activeKey: string, menu: GlobalMenuOption, rootPath: string) {
const list: GlobalBreadcrumb[] = [];
if (activeKey.includes(menu.routeName)) {
const breadcrumb: GlobalBreadcrumb = {
key: menu.routeName,
label: menu.label as string,
routeName: menu.routeName,
disabled: menu.routePath === rootPath,
hasChildren: false
};
if (menu.icon) {
breadcrumb.icon = menu.icon;
/**
* 根据菜单数据获取面包屑格式的菜单
* @param activeKey - 当前页面路由的key
* @param menus - 菜单数据
*/
function getBreadcrumbMenu(activeKey: string, menus: GlobalMenuOption[]) {
const breadcrumbMenu: GlobalMenuOption[] = [];
menus.some(menu => {
const flag = activeKey.includes(menu.routeName);
if (flag) {
breadcrumbMenu.push(...getBreadcrumbMenuItem(activeKey, menu));
}
if (menu.children && menu.children.length) {
breadcrumb.hasChildren = true;
breadcrumb.children = menu.children
.map(item => getBreadcrumbItem(activeKey, item as GlobalMenuOption, rootPath))
.flat(1);
}
list.push(breadcrumb);
}
return list;
return flag;
});
return breadcrumbMenu;
}
/**
* 根据单个菜单数据获取面包屑格式的菜单
* @param activeKey - 当前页面路由的key
* @param menu - 单个菜单数据
*/
function getBreadcrumbMenuItem(activeKey: string, menu: GlobalMenuOption) {
const breadcrumbMenu: GlobalMenuOption[] = [];
if (activeKey.includes(menu.routeName)) {
breadcrumbMenu.push(menu);
}
if (menu.children && menu.children.length) {
breadcrumbMenu.push(
...menu.children.map(item => getBreadcrumbMenuItem(activeKey, item as GlobalMenuOption)).flat(1)
);
}
return breadcrumbMenu;
}
/**
* 将面包屑格式的菜单数据转换成面包屑数据
* @param menu - 单个菜单数据
* @param rootPath - 根路由路径
*/
function transformBreadcrumbMenuToBreadcrumb(menu: GlobalMenuOption, rootPath: string) {
const hasChildren = Boolean(menu.children && menu.children.length);
const breadcrumb: GlobalBreadcrumb = {
key: menu.routeName,
label: menu.label as string,
routeName: menu.routeName,
disabled: menu.routePath === rootPath,
hasChildren
};
if (menu.icon) {
breadcrumb.icon = menu.icon;
}
if (hasChildren) {
breadcrumb.children = menu.children?.map(item =>
transformBreadcrumbMenuToBreadcrumb(item as GlobalMenuOption, rootPath)
);
}
return breadcrumb;
}