11<template >
2- <view :style =" customStyle" :class =" `wd-drop-menu ${customClass}`" @click.stop =" noop" :id =" dropMenuId" >
2+ <view :style =" customStyle" :class =" `wd-drop-menu ${customClass}`" @click.stop.prevent =" noop" :id =" dropMenuId" >
3+ <wd-overlay :show =" overlayVisible" :duration =" duration" :z-index =" 12" :custom-style =" modalStyle" @click =" handleClickOverlay" @touchmove =" noop" />
4+
35 <!-- #ifdef MP-DINGTALK -->
46 <view :id =" dropMenuId" >
57 <!-- #endif -->
@@ -34,23 +36,52 @@ export default {
3436 </script >
3537
3638<script lang="ts" setup>
37- import { getCurrentInstance , inject , onBeforeMount , ref , watch } from ' vue'
39+ import { computed , getCurrentInstance , inject , onBeforeMount , ref , watch } from ' vue'
3840import { closeOther } from ' ../common/clickoutside'
3941import { type Queue , queueKey } from ' ../composables/useQueue'
4042import { getRect , uuid } from ' ../common/util'
4143import { useChildren } from ' ../composables/useChildren'
4244import { DROP_MENU_KEY , dropMenuProps } from ' ./types'
45+ import wdOverlay from ' ../wd-overlay/wd-overlay.vue'
4346
4447const props = defineProps (dropMenuProps )
4548const queue = inject <Queue | null >(queueKey , null )
4649const dropMenuId = ref <string >(` dropMenuId${uuid ()} ` )
4750const offset = ref <number >(0 )
4851const windowHeight = ref <number >(0 )
52+ const modalStyle = computed (() => {
53+ return props .direction === ' down'
54+ ? ` top: calc(var(--window-top) + ${offset .value }px); bottom: 0; `
55+ : ` top: 0; bottom: calc(var(--window-bottom) + ${offset .value }px) `
56+ })
4957
5058const { proxy } = getCurrentInstance () as any
5159
5260const { linkChildren, children } = useChildren (DROP_MENU_KEY )
5361
62+ const showOverlay = computed (() => {
63+ return children .some ((child ) => child .$ .exposed ! .getShowPop ())
64+ })
65+
66+ const overlayVisible = ref (false )
67+ let overlayTimer: ReturnType <typeof setTimeout > | null
68+
69+ // 延迟关闭遮罩层,避免闪烁
70+ // 小程序中,即使先 fold 再 closeOther 也会有闪烁,使用延迟关闭遮罩层处理
71+ watch (showOverlay , (newVal ) => {
72+ if (overlayTimer ) {
73+ clearTimeout (overlayTimer )
74+ }
75+ if (newVal ) {
76+ overlayVisible .value = true
77+ } else {
78+ overlayTimer = setTimeout (() => {
79+ overlayVisible .value = false
80+ overlayTimer = null
81+ }, 16 )
82+ }
83+ })
84+
5485linkChildren ({ props , fold , offset })
5586
5687watch (
@@ -68,10 +99,7 @@ onBeforeMount(() => {
6899 windowHeight .value = uni .getSystemInfoSync ().windowHeight
69100})
70101
71- function noop(event : Event ) {
72- event .preventDefault ()
73- event .stopPropagation ()
74- }
102+ function noop() {}
75103
76104function getDisplayTitle(child : any ) {
77105 const { title, modelValue, options, valueKey, labelKey } = child
@@ -114,6 +142,15 @@ function fold(child: any) {
114142 child .$ .exposed ! .toggle ()
115143 })
116144}
145+
146+ function handleClickOverlay() {
147+ if (props .closeOnClickModal ) {
148+ // 关闭所有打开的菜单项
149+ children .forEach ((child ) => {
150+ child .$ .exposed ! .close ()
151+ })
152+ }
153+ }
117154 </script >
118155
119156<style lang="scss" scoped>
0 commit comments