|
@@ -1,5 +1,5 @@
|
|
|
<script setup lang="ts">
|
|
|
-import { useElementSize } from '@vueuse/core'
|
|
|
+import { useElementSize, watchThrottled } from '@vueuse/core'
|
|
|
import { isFunction, isEmpty } from 'lodash-es'
|
|
|
import { NDropdown } from 'naive-ui'
|
|
|
import { h, computed, ref, watch, nextTick, onBeforeUnmount } from 'vue'
|
|
@@ -20,6 +20,9 @@ const MENU_SIZE = {
|
|
|
BOUNDARY_OFFSET: 1,
|
|
|
}
|
|
|
|
|
|
+let rafId: number | null = null
|
|
|
+let initialized = false
|
|
|
+
|
|
|
const userStore = useUserStore()
|
|
|
|
|
|
const { navigationContainerElement } = useInjection(headerLayoutInjectionKey)
|
|
@@ -56,8 +59,9 @@ function forwardRef(key: Key, ref: Element | ComponentPublicInstance | null) {
|
|
|
const rect = (ref as HTMLElement).getBoundingClientRect()
|
|
|
menuRightBoundMap.set(
|
|
|
key,
|
|
|
- rect.right - navigationWrapperRef.value!.getBoundingClientRect().left,
|
|
|
+ rect.right - (navigationWrapperRef.value?.getBoundingClientRect().left ?? 0),
|
|
|
)
|
|
|
+ scheduleUpdateMenuVisibility()
|
|
|
})
|
|
|
}
|
|
|
|
|
@@ -75,6 +79,15 @@ function updateMenuVisibility(containerWidth: number) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+function scheduleUpdateMenuVisibility() {
|
|
|
+ if (rafId != null) return
|
|
|
+ rafId = requestAnimationFrame(() => {
|
|
|
+ rafId = null
|
|
|
+ updateMenuVisibility(containerWidth.value)
|
|
|
+ if (!initialized) initialized = true
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
function hasActiveChild(children: any[]): boolean {
|
|
|
const stack = [...children]
|
|
|
while (stack.length) {
|
|
@@ -97,9 +110,16 @@ watch(
|
|
|
},
|
|
|
)
|
|
|
|
|
|
-watch(containerWidth, (width) => {
|
|
|
- updateMenuVisibility(width)
|
|
|
-})
|
|
|
+watchThrottled(
|
|
|
+ containerWidth,
|
|
|
+ (width) => {
|
|
|
+ if (!initialized) return
|
|
|
+ updateMenuVisibility(width)
|
|
|
+ },
|
|
|
+ {
|
|
|
+ throttle: 100,
|
|
|
+ },
|
|
|
+)
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
stopObserveContainerWidth()
|