From 7783872ef617f053538ac18b99c233630b95cffa Mon Sep 17 00:00:00 2001 From: XiaoDaiGua-Ray <443547225@qq.com> Date: Wed, 23 Oct 2024 20:48:01 +0800 Subject: [PATCH] version: v5.0.2 --- CHANGELOG.md | 13 +++++++ package.json | 2 +- src/layout/components/Menu/index.tsx | 1 - src/layout/components/MenuTag/index.tsx | 35 ++++++++--------- .../components/SettingDrawer/index.tsx | 38 +++++++++++++++++-- src/store/hooks/useMenuStore.ts | 2 + src/store/modules/menu/index.ts | 1 + 7 files changed, 69 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60e1c147..36f089b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # CHANGE LOG +## 5.0.2 + +## Feats + +- 暴露 `setupAppMenu` 方法,提供自定义菜单渲染时机能力 + +## Fixes + +- 修复 `MenuTag` 右键菜单不能被选中的问题 +- 修复 `Menu` 设置 `iconSize`, `iconCollapseSize` 等属性,不能及时刷新渲染的问题,现在新增手动刷新操作按钮 + +> 菜单渲染是很复杂、很耗时的操作,所以在权衡以后还是考虑使用手动刷新操作方式更新菜单状态。 + ## 5.0.1 本次更新灵感来自于 `vben admin 5` 项目。 diff --git a/package.json b/package.json index 9c0b6c4d..88d8e35a 100755 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ray-template", "private": false, - "version": "5.0.1", + "version": "5.0.2", "type": "module", "engines": { "node": "^18.0.0 || >=20.0.0", diff --git a/src/layout/components/Menu/index.tsx b/src/layout/components/Menu/index.tsx index 71186448..db9537b2 100644 --- a/src/layout/components/Menu/index.tsx +++ b/src/layout/components/Menu/index.tsx @@ -21,7 +21,6 @@ export default defineComponent({ useMenuActions() const { getMenuConfig } = useSettingGetters() const { getMenuOptions, getCollapsed, getMenuKey } = useMenuGetters() - const modelMenuKey = computed({ get: () => { // eslint-disable-next-line vue/no-async-in-computed-properties diff --git a/src/layout/components/MenuTag/index.tsx b/src/layout/components/MenuTag/index.tsx index 8e2ea794..7f1cf3f7 100644 --- a/src/layout/components/MenuTag/index.tsx +++ b/src/layout/components/MenuTag/index.tsx @@ -16,7 +16,7 @@ * 该模板中引入了 Root Path 概念,在 MenuTag 中除了关闭左右侧标签操作能主动移除 Root Tag 之外其余的操作都不允许。 * * outsideClick 方法优先级不如 contextmenu 事件高,所以可能会出现重复右键菜单时,闪烁问题; - * 虽然使用 throttle 方法进行优化,但是该问题本质并没有解决(v5.0.1 版本修复了该问题)。 + * 虽然使用 throttle 方法进行优化,但是该问题本质并没有解决(v5.0.2 版本修复了该问题)。 */ import './index.scss' @@ -34,7 +34,6 @@ import { RIcon, RMoreDropdown } from '@/components' import { useMenuGetters, useMenuActions } from '@/store' import { hasClass, uuid, queryElements } from '@/utils' import { useMaximize, useSpinning, useAppRoot, useSiderBar } from '@/hooks' -import { throttle } from 'lodash-es' import { getVariableToRefs } from '@/global-variable' import { useTemplateRef } from 'vue' @@ -65,7 +64,6 @@ export default defineComponent({ 'closeRight', 'closeLeft', 'closeOther', - 'closeCurrentPage', ] // 当前右键标签页索引位置 let currentContextmenuIndex = Infinity @@ -179,6 +177,8 @@ export default defineComponent({ const naiveScrollbarContainerClass = 'n-scrollbar-container' // 缓存上一次的菜单 key let catchMenuKey = getMenuKey.value + // 当前鼠标是否划入 menu tag + const isMouseInMenuTag = ref(false) // 关闭当前菜单标签,如果只有一个标签,则不允许关闭 const closeCurrentMenuTag = (idx: number) => { @@ -260,21 +260,14 @@ export default defineComponent({ actionState.actionDropdownShow = false nextTick(() => { - actionState.actionDropdownShow = true actionState.x = e.clientX actionState.y = e.clientY + actionState.actionDropdownShow = true }) } // 动态设置某些项禁用 const setDisabledAccordionToIndex = () => { - const { closeable } = - getMenuTagOptions.value[currentContextmenuIndex] ?? - ({} as MenuTagOptions) - - // 是否需要禁用关闭当前标签页 - setMoreOptionsDisabled('closeCurrentPage', !closeable ?? false) - // 是否需要禁用关闭右侧标签页 checkCloseRight(currentContextmenuIndex) ? setMoreOptionsDisabled('closeRight', false) @@ -306,6 +299,8 @@ export default defineComponent({ ) { option.closeable = true } + + isMouseInMenuTag.value = true } // 移出 MenuTag 时,判断是否为当前已激活 key @@ -313,6 +308,8 @@ export default defineComponent({ if (option.fullPath !== getMenuKey.value) { option.closeable = false } + + isMouseInMenuTag.value = false } // 每当新的页面打开后,将滚动条横向滚到至底部,使用 nextTick 避免元素未渲染挂载至页面 @@ -359,7 +356,7 @@ export default defineComponent({ (ndata, odata) => { // 当 menuTagOptions 长度为 1时,禁用所有 canDisabledOptions 匹配的项 moreOptions.value.forEach((curr) => { - if (canDisabledOptions.includes(curr.key)) { + if (canDisabledOptions.includes(curr.key as string)) { ndata.length > 1 ? (curr.disabled = false) : (curr.disabled = true) } }) @@ -384,8 +381,7 @@ export default defineComponent({ ) watchEffect(() => { if (actionState.actionDropdownShow) { - // 使用节流函数,避免右键菜单闪烁问题 - throttle(setDisabledAccordionToIndex, 300)?.() + setDisabledAccordionToIndex() } if (catchMenuKey !== getMenuKey.value) { @@ -418,6 +414,7 @@ export default defineComponent({ reload, globalMainLayoutLoad, maximizeBtnClick, + isMouseInMenuTag, } }, render() { @@ -427,6 +424,7 @@ export default defineComponent({ getMenuTagOptions, MENU_TAG_DATA, globalMainLayoutLoad, + isMouseInMenuTag, } = this const { maximizeBtnClick, @@ -454,6 +452,11 @@ export default defineComponent({ trigger="manual" placement="bottom-start" onSelect={actionDropdownSelect.bind(this)} + onClickoutside={() => { + if (!isMouseInMenuTag) { + this.actionState.actionDropdownShow = false + } + }} /> { - this.actionState.actionDropdownShow = false - }, [MENU_TAG_DATA]: curr.fullPath, }} size="small" + focusable={false} > {{ default: () => ( diff --git a/src/layout/components/SiderBar/components/SettingDrawer/index.tsx b/src/layout/components/SiderBar/components/SettingDrawer/index.tsx index 67cad50d..e9dc0862 100644 --- a/src/layout/components/SiderBar/components/SettingDrawer/index.tsx +++ b/src/layout/components/SiderBar/components/SettingDrawer/index.tsx @@ -21,9 +21,9 @@ import ThemeSegment from './components/ThemeSegment' import { RIcon } from '@/components' import { APP_THEME, CONTENT_TRANSITION_OPTIONS } from '@/app-config' -import { useSettingGetters, useSettingActions } from '@/store' +import { useSettingGetters, useSettingActions, useMenuActions } from '@/store' import { defaultSettingConfig } from './constant' -import { forIn } from 'lodash-es' +import { forIn, throttle } from 'lodash-es' import type { PropType } from 'vue' import type { Placement } from '@/types' @@ -60,6 +60,7 @@ export default defineComponent({ getMenuConfig, getDrawerPlacement, } = useSettingGetters() + const { setupAppMenu } = useMenuActions() const modelShow = computed({ get: () => props.show, @@ -84,10 +85,14 @@ export default defineComponent({ set: (value) => {}, }) + const throttleSetupAppMenu = throttle(setupAppMenu, 300) + const defaultSettingBtnClick = () => { forIn(defaultSettingConfig, (value, key) => { updateSettingState(key as keyof SettingState, value) }) + + throttleSetupAppMenu() } return { @@ -98,6 +103,7 @@ export default defineComponent({ updateSettingState, modelReactive, defaultSettingBtnClick, + throttleSetupAppMenu, } }, render() { @@ -106,6 +112,7 @@ export default defineComponent({ changePrimaryColor, updateSettingState, defaultSettingBtnClick, + throttleSetupAppMenu, } = this return ( @@ -226,7 +233,17 @@ export default defineComponent({ /> - 菜单样式 + + + + {{ + trigger: () => , + default: () => '菜单渲染是一个复杂、耗时的操作,请手动更新', + }} + + 菜单样式 + + - + + + + {{ + icon: () => , + default: () => '点击刷新', + }} + + diff --git a/src/store/hooks/useMenuStore.ts b/src/store/hooks/useMenuStore.ts index ef0a9d3f..72c8a90e 100644 --- a/src/store/hooks/useMenuStore.ts +++ b/src/store/hooks/useMenuStore.ts @@ -73,6 +73,7 @@ export const useMenuActions = () => { setMenuTagOptions, resolveOption, updateMenuState, + setupAppMenu, } = piniaMenuStore() return { @@ -82,5 +83,6 @@ export const useMenuActions = () => { setMenuTagOptions, resolveOption, updateMenuState, + setupAppMenu, } } diff --git a/src/store/modules/menu/index.ts b/src/store/modules/menu/index.ts index 71cb9457..07b89b19 100644 --- a/src/store/modules/menu/index.ts +++ b/src/store/modules/menu/index.ts @@ -436,6 +436,7 @@ export const piniaMenuStore = defineStore( setMenuTagOptions, resolveOption, updateMenuState, + setupAppMenu, } }, {