AnimatedOverlay.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <!-- BottomPopup.vue -->
  2. <template>
  3. <!-- 最外层用 transition 做遮罩的淡入淡出 -->
  4. <transition :name="overlayTransitionName">
  5. <!-- 遮罩 -->
  6. <div
  7. v-show="visible"
  8. class="overlay-mask"
  9. :class="overlayClass"
  10. @click.self="clickOverlay"
  11. >
  12. <!-- 内容区用另一个 transition 实现从底部滑出 -->
  13. <transition :name="contentTransitionName">
  14. <div v-show="visible" class="overlay-content" :class="overlayClass">
  15. <!-- 可定制的区域 -->
  16. <slot />
  17. </div>
  18. </transition>
  19. </div>
  20. </transition>
  21. </template>
  22. <script>
  23. export default {
  24. name: 'CommonDialog',
  25. props: {
  26. // 受控显示/隐藏
  27. visible: {
  28. type: Boolean,
  29. default: false
  30. },
  31. overlayTransitionName: {
  32. type: String,
  33. default: 'fade', // fade/slide-up
  34. },
  35. contentTransitionName: {
  36. type: String,
  37. default: '',
  38. },
  39. contentContainerClass: {
  40. type: String,
  41. default: ''
  42. },
  43. contentClass: {
  44. type: String,
  45. default: ''
  46. },
  47. overlayClass: {
  48. type: String,
  49. default: ''
  50. },
  51. },
  52. watch: {
  53. // 简单处理 body 滚动
  54. visible(val) {
  55. if (val) {
  56. document.body.style.overflow = 'hidden'
  57. }
  58. else {
  59. document.body.style.overflow = ''
  60. }
  61. }
  62. },
  63. methods: {
  64. clickOverlay() {
  65. this.syncVisible(false)
  66. },
  67. syncVisible(f = false) {
  68. this.$emit('update:visible', f)
  69. },
  70. }
  71. }
  72. </script>
  73. <style scoped lang="scss">
  74. /* 遮罩 */
  75. .overlay-mask {
  76. position: fixed;
  77. top: 0;
  78. left: 0;
  79. width: 100%;
  80. height: 100%;
  81. background: rgba(0, 0, 0, 0.5);
  82. z-index: 999;
  83. }
  84. /* 遮罩淡入淡出 */
  85. .fade-enter-active,
  86. .fade-leave-active {
  87. transition: opacity 0.3s;
  88. }
  89. .fade-enter,
  90. .fade-leave-to {
  91. opacity: 0;
  92. }
  93. /* 内容从底部滑出 */
  94. .slide-up-enter-active,
  95. .slide-up-leave-active {
  96. transition: transform 0.3s ease-out;
  97. }
  98. .slide-up-enter,
  99. .slide-up-leave-to {
  100. transform: translate3d(0, 100%, 0);
  101. }
  102. </style>