77 ref ,
88 Transition ,
99 nextTick ,
10- onMounted ,
1110} from ' vue' ;
1211import type { PropType } from ' vue' ;
1312
@@ -39,8 +38,11 @@ export default defineComponent({
3938 },
4039 /** 显示的内容,也可以通过写入默认 slot 修改显示内容 */
4140 content: String ,
41+ /** 弹出位置 */
4242 placement: {
43- type: String as PropType <' top' | ' bottom' | ' left' | ' right' >,
43+ type: String as PropType <
44+ ' topStart' | ' top' | ' topEnd' | ' bottomStart' | ' bottom' | ' bottomEnd'
45+ >,
4446 default: ' top' ,
4547 },
4648 },
@@ -49,20 +51,32 @@ export default defineComponent({
4951
5052 const $popover = ref <HTMLDivElement >();
5153
52- const posStyle = ref ();
54+ let closeT: number | undefined ;
55+
56+ const posStyle = ref ({});
5357
5458 function handleMouseEnter(e : Event ) {
59+ if (show .value ) {
60+ if (closeT != null ) {
61+ clearTimeout (closeT );
62+ closeT = undefined ;
63+ }
64+ return ;
65+ }
5566 const $target = e .target as HTMLElement ;
5667 show .value = true ;
57- console .log (' enter' );
5868 nextTick (() => {
5969 const { left, top } = getDistanceToContainer ($target );
6070 let offsetTop = 0 ;
6171 let offsetLeft = 0 ;
6272 if ($popover .value != null ) {
6373 const popoverRect = $popover .value .getBoundingClientRect ();
64- offsetTop = popoverRect .height + 10 ;
6574 const targetRect = $target .getBoundingClientRect ();
75+ if (props .placement === ' top' ) {
76+ offsetTop = popoverRect .height + 10 ;
77+ } else if (props .placement === ' bottom' ) {
78+ offsetTop = - (targetRect .height + 10 );
79+ }
6680 offsetLeft = popoverRect .width / 2 - targetRect .width / 2 ;
6781 }
6882 posStyle .value = {
@@ -74,7 +88,9 @@ export default defineComponent({
7488
7589 /** 鼠标离开事件 */
7690 function hanldeMouseLeave() {
77- show .value = false ;
91+ closeT = setTimeout (() => {
92+ show .value = false ;
93+ }, 150 ) as any ;
7894 }
7995
8096 function handleClick(e : Event ) {
@@ -108,9 +124,25 @@ export default defineComponent({
108124 ' div' ,
109125 {
110126 ... attrs ,
111- class: [' nt-popover' , attrs .class ],
127+ class: [
128+ ' nt-popover' ,
129+ props .placement .startsWith (' top' )
130+ ? ' nt-popover-top'
131+ : ' ' ,
132+ props .placement .startsWith (' bottom' )
133+ ? ' nt-popover-bottom'
134+ : ' ' ,
135+ props .placement .endsWith (' Start' )
136+ ? ' nt-popover-start'
137+ : ' ' ,
138+ props .placement .endsWith (' End' )
139+ ? ' nt-popover-end'
140+ : ' ' ,
141+ attrs .class ,
142+ ],
112143 style: [attrs .style , posStyle .value ],
113144 ref: $popover ,
145+ ... prop ,
114146 },
115147 [
116148 slots .default != null
0 commit comments