index.vue 1.9 KB

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