99 watch ,
1010 Slots ,
1111 toRefs ,
12- reactive ,
1312 nextTick ,
1413 Transition ,
1514} from 'vue' ;
@@ -100,26 +99,24 @@ export default defineComponent({
10099 } ,
101100 ] ) ;
102101
103- provide < TdSubMenuInterface > (
104- 'TdSubmenu' ,
105- reactive ( {
106- value,
107- addMenuItem : ( item : TdMenuItem ) => {
108- menuItems . value . push ( item ) ;
109- if ( submenu ) {
110- submenu . addMenuItem ( item ) ;
111- }
112- } ,
113- setSubPopup : ( ref : HTMLElement ) => {
114- subPopupRef . value = ref ;
115- } ,
116- closeParentPopup : ( e : MouseEvent ) => {
117- const related = e . relatedTarget as HTMLElement ;
118- if ( loopInPopup ( related ) ) return ;
119- handleMouseLeavePopup ( e ) ;
120- } ,
121- } ) ,
122- ) ;
102+ provide < TdSubMenuInterface > ( 'TdSubmenu' , {
103+ value : value . value ,
104+ popupVisible,
105+ addMenuItem : ( item : TdMenuItem ) => {
106+ menuItems . value . push ( item ) ;
107+ if ( submenu ) {
108+ submenu . addMenuItem ( item ) ;
109+ }
110+ } ,
111+ setSubPopup : ( ref : HTMLElement ) => {
112+ subPopupRef . value = ref ;
113+ } ,
114+ closeParentPopup : ( e : MouseEvent ) => {
115+ const related = e . relatedTarget as HTMLElement ;
116+ if ( loopInPopup ( related ) ) return ;
117+ handleMouseLeavePopup ( e ) ;
118+ } ,
119+ } ) ;
123120
124121 const passSubPopupRefToParent = ( val : HTMLElement ) => {
125122 if ( isFunction ( setSubPopup ) ) {
@@ -128,8 +125,31 @@ export default defineComponent({
128125 } ;
129126
130127 // methods
131- const handleMouseEnter = ( ) => {
128+ const handleMouseEnter = ( e ?: MouseEvent ) => {
132129 if ( props . disabled ) return ;
130+
131+ // 如果是嵌套子菜单,检查父级 popup 是否可见
132+ if ( isNested . value && submenu ?. popupVisible ) {
133+ if ( ! submenu . popupVisible . value ) {
134+ return ;
135+ }
136+ // 如果父 popup 可见,还需要检查鼠标是否真的在父 popup 内
137+ // 避免父 popup 延迟关闭时,鼠标已经移出但子菜单仍被触发
138+ if ( e && subPopupRef . value ) {
139+ const parentPopupRect = subPopupRef . value . getBoundingClientRect ( ) ;
140+ const { clientX, clientY } = e ;
141+ const isInParentPopup =
142+ clientX >= parentPopupRect . left &&
143+ clientX <= parentPopupRect . right &&
144+ clientY >= parentPopupRect . top &&
145+ clientY <= parentPopupRect . bottom ;
146+
147+ if ( ! isInParentPopup ) {
148+ return ;
149+ }
150+ }
151+ }
152+
133153 setTimeout ( ( ) => {
134154 if ( ! popupVisible . value ) {
135155 open ( props . value ) ;
0 commit comments