index.vue 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template>
  2. <div
  3. v-if="isOverlayShow"
  4. ref="overlayDomRef"
  5. class="overlay-container"
  6. :style="{
  7. position: props.isFullScreen ? 'fixed' : 'absolute',
  8. zIndex: props.zIndex,
  9. }"
  10. >
  11. <div
  12. v-if="props.useMask"
  13. :class="{
  14. 'overlay-mask': true,
  15. 'fade-in': props.visible,
  16. }"
  17. :style="{
  18. backgroundColor: props.maskColor,
  19. }"
  20. @click="onOverlayClick"
  21. @touchstart.prevent.stop="onOverlayClick"
  22. />
  23. <div
  24. :class="{
  25. 'overlay-content': true,
  26. 'full-screen': props.isFullScreen,
  27. }"
  28. >
  29. <slot />
  30. </div>
  31. </div>
  32. </template>
  33. <script setup lang="ts">
  34. import { ref, watch, withDefaults } from '../../../adapter-vue';
  35. export interface IOverlayProps {
  36. visible?: boolean;
  37. zIndex?: number | undefined;
  38. useMask?: boolean | undefined;
  39. maskColor?: string | undefined;
  40. isFullScreen?: boolean | undefined;
  41. width?: string;
  42. height?: string;
  43. }
  44. const emits = defineEmits(['onOverlayClick']);
  45. const props = withDefaults(defineProps<IOverlayProps>(), {
  46. visible: true,
  47. zIndex: 9999,
  48. useMask: true,
  49. isFullScreen: true,
  50. maskColor: 'rgba(0, 0, 0, 0.6)',
  51. width: 'auto',
  52. height: 'auto',
  53. });
  54. const overlayDomRef = ref<HTMLElement>();
  55. const isOverlayShow = ref<boolean>(props.visible);
  56. watch(() => props.visible, (visible: boolean) => {
  57. if (visible) {
  58. isOverlayShow.value = true;
  59. } else {
  60. setTimeout(() => {
  61. isOverlayShow.value = false;
  62. }, 150);
  63. }
  64. }, {
  65. immediate: true,
  66. });
  67. function onOverlayClick() {
  68. emits('onOverlayClick');
  69. }
  70. defineExpose({
  71. overlayDomRef,
  72. });
  73. </script>
  74. <style scoped lang="scss">
  75. .overlay-container {
  76. position: fixed;
  77. top: 0;
  78. bottom: 0;
  79. left: 0;
  80. right: 0;
  81. z-index: 9999;
  82. display: flex;
  83. align-items: center;
  84. justify-content: center;
  85. .overlay-mask {
  86. z-index: -1;
  87. position: absolute;
  88. top: 0;
  89. left: 0;
  90. right: 0;
  91. bottom: 0;
  92. background-color: rgba(0, 0, 0, 0.6);
  93. opacity: 0;
  94. transition: opacity 0.15s linear;
  95. animation: fade-in 0.15s linear;
  96. }
  97. }
  98. .overlay-mask.fade-in {
  99. opacity: 1;
  100. }
  101. @keyframes fade-in {
  102. 0% {
  103. opacity: 0;
  104. }
  105. 100% {
  106. opacity: 1;
  107. }
  108. }
  109. </style>