VUE3一个弹窗问题?

vue3的弹窗组件,现在有一个问题就是,当我点击打开弹窗后,鼠标在弹窗内按下不松开,移到弹窗外再松开,怎么样让他不关闭,如果是单独点击弹窗外,正常关闭。

<script setup>
const show = ref(false)
const open = () => {
    show.value = true;
    window.addEventListener('click', close);
}
const close = () => {
    show.value = false;
    window.removeEventListener('click', close);
}
</script>

<template>
    <button @click.stop.prevent="open()" type="button">打开</button>
    <div v-if="show" @click.stop.prevent style="background: #000000; width: 300px; height: 300px;">
        <h1>弹窗</h1>
        <button @click.stop.prevent="close()" type="button">关闭</button>
    </div>
</template>

<style scoped>

</style>
阅读 998
2 个回答
<script setup>
import { ref } from 'vue';

const show = ref(false);
let isMouseDownInside = false;

const open = () => {
  if (show.value) return; // 防止重复打开
  show.value = true;
  window.addEventListener('mousedown', handleMouseDown);
  window.addEventListener('mouseup', handleMouseUp);
};

const close = () => {
  show.value = false;
  window.removeEventListener('mousedown', handleMouseDown);
  window.removeEventListener('mouseup', handleMouseUp);
};

const handleMouseDown = (event) => {
  isMouseDownInside = !!event.target.closest('.modal');
};

const handleMouseUp = (event) => {
  const isMouseUpInside = !!event.target.closest('.modal');
  if (!isMouseUpInside && !isMouseDownInside) {
    close();
  }
  isMouseDownInside = false;
};
</script>

<template>
  <button @click="open" type="button">打开</button>
  <div v-if="show" class="modal" @click.stop @mouseup.stop style="background: #000000; width: 300px; height: 300px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);">
    <h1>弹窗</h1>
    <button @click="close" type="button">关闭</button>
  </div>
</template>

<style scoped>
.modal {
  z-index: 1000;
}
</style>

大哥,我改成了这样,因为你那个还没开打的时候就已经绑定了事件,并且关闭了事件还在,是不是应该不对,现在还有一个问题就是,点击弹窗内好像事件还是会触发,是不是应该不对?点击弹窗内是不是应该没事件,点击弹窗外才有?

<script setup>
const show = ref(false);
let isMouseDownInside = false; // 使用普通变量,非响应式

const open = () => {
    show.value = true;
    window.addEventListener('mousedown', handleMouseDown);
    window.addEventListener('mouseup', handleMouseUp);
};

const close = () => {
    show.value = false;
    window.removeEventListener('mousedown', handleMouseDown);
    window.removeEventListener('mouseup', handleMouseUp);
};

const handleMouseDown = (event) => {
    console.log('handleMouseDown')
    isMouseDownInside = !!event.target.closest('.modal'); // 检查是否在弹窗内
};

const handleMouseUp = (event) => {
    console.log('handleMouseUp')
    if (!event.target.closest('.modal') && !isMouseDownInside) {
        close(); // 仅当mouseup在外部且mousedown不在弹窗内时关闭
    }
    isMouseDownInside = false; // 重置状态
};

onMounted(() => {
    // window.addEventListener('mousedown', handleMouseDown);
    // window.addEventListener('mouseup', handleMouseUp);
});

onUnmounted(() => {
    // window.removeEventListener('mousedown', handleMouseDown);
    // window.removeEventListener('mouseup', handleMouseUp);
});
</script>

<template>
    <button @click="open" type="button">打开</button>
    <div v-if="show" class="modal" @click.stop style="background: #000000; width: 300px; height: 300px; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);">
        <h1>弹窗</h1>
        <button @click="close" type="button">关闭</button>
    </div>
</template>

<style scoped>
.modal {
    z-index: 1000; /* 确保弹窗在最上层 */
}
</style>
推荐问题