Skip to content

Commit 10c8401

Browse files
committed
perf: 优化子菜单过渡效果,支持两套实现方案
1 parent b0ac061 commit 10c8401

File tree

1 file changed

+40
-37
lines changed

1 file changed

+40
-37
lines changed

‎src/layouts/components/Menu/sub.vue‎

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<script setup lang="ts">
22
import type { SubMenuProps } from './types'
3+
import { cn } from '@/utils'
34
import { useTimeoutFn } from '@vueuse/core'
45
import Item from './item.vue'
56
import { rootMenuInjectionKey } from './types'
@@ -45,40 +46,42 @@ const transitionEvent = computed(() => {
4546
el.style.overflow = ''
4647
},
4748
}
48-
: {
49-
enter(el: HTMLElement) {
50-
requestAnimationFrame(() => {
51-
el.dataset.height = el.offsetHeight.toString()
52-
el.style.maxHeight = '0'
53-
void el.offsetHeight
54-
el.style.maxHeight = `${el.dataset.height}px`
49+
: CSS.supports('height', 'calc-size(auto, size)')
50+
? {}
51+
: {
52+
enter(el: HTMLElement) {
53+
requestAnimationFrame(() => {
54+
el.dataset.height = el.offsetHeight.toString()
55+
el.style.maxHeight = '0'
56+
void el.offsetHeight
57+
el.style.maxHeight = `${el.dataset.height}px`
58+
el.style.overflow = 'hidden'
59+
})
60+
},
61+
afterEnter(el: HTMLElement) {
62+
el.style.maxHeight = ''
63+
el.style.overflow = ''
64+
},
65+
enterCancelled(el: HTMLElement) {
66+
el.style.maxHeight = ''
67+
el.style.overflow = ''
68+
},
69+
beforeLeave(el: HTMLElement) {
70+
el.style.maxHeight = `${el.offsetHeight}px`
5571
el.style.overflow = 'hidden'
56-
})
57-
},
58-
afterEnter(el: HTMLElement) {
59-
el.style.maxHeight = ''
60-
el.style.overflow = ''
61-
},
62-
enterCancelled(el: HTMLElement) {
63-
el.style.maxHeight = ''
64-
el.style.overflow = ''
65-
},
66-
beforeLeave(el: HTMLElement) {
67-
el.style.maxHeight = `${el.offsetHeight}px`
68-
el.style.overflow = 'hidden'
69-
},
70-
leave(el: HTMLElement) {
71-
el.style.maxHeight = '0'
72-
},
73-
afterLeave(el: HTMLElement) {
74-
el.style.maxHeight = ''
75-
el.style.overflow = ''
76-
},
77-
leaveCancelled(el: HTMLElement) {
78-
el.style.maxHeight = ''
79-
el.style.overflow = ''
80-
},
81-
}
72+
},
73+
leave(el: HTMLElement) {
74+
el.style.maxHeight = '0'
75+
},
76+
afterLeave(el: HTMLElement) {
77+
el.style.maxHeight = ''
78+
el.style.overflow = ''
79+
},
80+
leaveCancelled(el: HTMLElement) {
81+
el.style.maxHeight = ''
82+
el.style.overflow = ''
83+
},
84+
}
8285
})
8386
8487
const transitionClass = computed(() => {
@@ -93,11 +96,11 @@ const transitionClass = computed(() => {
9396
}
9497
: {
9598
enterActiveClass: 'ease-in-out duration-300',
96-
enterFromClass: 'opacity-0 translate-y-4 scale-95 blur-4',
99+
enterFromClass: cn('opacity-0 translate-y-4 scale-95 blur-4', CSS.supports('height', 'calc-size(auto, size)') && 'h-0'),
97100
enterToClass: 'opacity-100 translate-y-0 scale-100 blur-0',
98101
leaveActiveClass: 'ease-in-out duration-300',
99102
leaveFromClass: 'opacity-100 translate-y-0 scale-100 blur-0',
100-
leaveToClass: 'opacity-0 translate-y-4 scale-95 blur-4',
103+
leaveToClass: cn('opacity-0 translate-y-4 scale-95 blur-4', CSS.supports('height', 'calc-size(auto, size)') && 'h-0'),
101104
}
102105
})
103106
@@ -140,7 +143,7 @@ function handleMouseenter() {
140143
top = el.getBoundingClientRect().top + el.scrollTop
141144
left = el.getBoundingClientRect().left + el.getBoundingClientRect().width
142145
if (top + subMenuEl.offsetHeight > window.innerHeight) {
143-
top = window.innerHeight - subMenuEl.offsetHeight
146+
top = Math.max(0, window.innerHeight - subMenuEl.offsetHeight)
144147
}
145148
}
146149
else {
@@ -188,7 +191,7 @@ function handleMouseleave() {
188191
<Teleport v-if="hasChildren" to="body" :disabled="!rootMenu.isMenuPopup">
189192
<Transition v-bind="transitionClass" v-on="transitionEvent">
190193
<FaScrollArea
191-
v-if="opened" ref="subMenuRef" :scrollbar="false" :mask="rootMenu.isMenuPopup" class="sub-menu static rounded-lg" :class="{
194+
v-if="opened" ref="subMenuRef" :scrollbar="false" :mask="rootMenu.isMenuPopup" class="sub-menu static h-[calc-size(auto,size)] rounded-lg" :class="{
192195
'bg-[var(--g-sub-sidebar-bg)]': rootMenu.isMenuPopup,
193196
'border shadow-xl fixed! z-3000 w-[200px]': rootMenu.isMenuPopup,
194197
'mx-1': rootMenu.isMenuPopup && (rootMenu.props.mode === 'vertical' || level !== 0),

0 commit comments

Comments
 (0)