mirror of
https://github.com/m-xlsea/ruoyi-plus-soybean.git
synced 2025-09-24 07:49:47 +08:00
fix(projects): 修复面包屑数据
This commit is contained in:
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,5 @@ export type GlobalBreadcrumb = DropdownOption & {
|
||||
disabled: boolean;
|
||||
routeName: string;
|
||||
hasChildren: boolean;
|
||||
iconName?: string;
|
||||
children?: GlobalBreadcrumb[];
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user