SimplePopup.vue 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. <template>
  2. <teleport to="body">
  3. <!-- 遮罩层 -->
  4. <div
  5. v-if="isClose2 || isVisible"
  6. :class="[
  7. 'popup-overlay',
  8. isVisible ? 'open' : '',
  9. isClose2 ? 'close' : '',
  10. ]"
  11. @click="close"
  12. >
  13. <!-- 弹出框内容 -->
  14. <div class="popup-content" @click.stop>
  15. <slot />
  16. </div>
  17. </div>
  18. </teleport>
  19. </template>
  20. <script lang="ts" setup>
  21. import { ref } from 'vue';
  22. const emit = defineEmits([ 'change' ]);
  23. const isVisible = ref(false);
  24. const isClose2 = ref(false);
  25. const open = () => {
  26. isClose2.value = true;
  27. setTimeout(() => {
  28. isClose2.value = false;
  29. isVisible.value = true;
  30. emit('change', true);
  31. }, 100);
  32. };
  33. const close = () => {
  34. isClose2.value = true;
  35. isVisible.value = false;
  36. setTimeout(() => {
  37. isClose2.value = false;
  38. emit('change', false);
  39. }, 300);
  40. };
  41. defineExpose({
  42. open,
  43. close
  44. });
  45. </script>
  46. <style lang="scss">
  47. @use "@/assets/scss/colors";
  48. .popup-overlay {
  49. position: fixed;
  50. top: 0;
  51. left: 0;
  52. width: 100%;
  53. height: 100%;
  54. background-color: rgba(0, 0, 0, 0.5);
  55. display: flex;
  56. justify-content: center;
  57. align-items: center;
  58. z-index: 300;
  59. opacity: 0;
  60. transition: all 0.3s ease-in-out;
  61. &.open {
  62. opacity: 1;
  63. .popup-content {
  64. opacity: 1;
  65. transform: scale(1);
  66. }
  67. }
  68. &.close {
  69. pointer-events: none;
  70. .popup-content {
  71. opacity: 0;
  72. }
  73. }
  74. }
  75. .popup-content {
  76. position: relative;
  77. transition: all 0.3s ease-in-out;
  78. transform: scale(0.9);
  79. }
  80. </style>