popup.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <template>
  2. <div class="cube-popup" :style="{'z-index': zIndex}" :class="rootClass" v-show="isVisible">
  3. <div class="cube-popup-mask" @touchmove.prevent @click="maskClick">
  4. <slot name="mask"></slot>
  5. </div>
  6. <div class="cube-popup-container" @touchmove.prevent :class="containerClass">
  7. <div class="cube-popup-content" v-if="$slots.default">
  8. <slot></slot>
  9. </div>
  10. <div class="cube-popup-content" v-else v-html="content">
  11. </div>
  12. </div>
  13. </div>
  14. </template>
  15. <script type="text/ecmascript-6">
  16. import visibilityMixin from '../../common/mixins/visibility'
  17. import popupMixin from '../../common/mixins/popup'
  18. const COMPONENT_NAME = 'cube-popup'
  19. const EVENT_MASK_CLICK = 'mask-click'
  20. export default {
  21. name: COMPONENT_NAME,
  22. mixins: [visibilityMixin, popupMixin],
  23. props: {
  24. type: {
  25. type: String,
  26. default: ''
  27. },
  28. mask: {
  29. type: Boolean,
  30. default: true
  31. },
  32. content: {
  33. type: String,
  34. default: ''
  35. },
  36. center: {
  37. type: Boolean,
  38. default: true
  39. },
  40. position: {
  41. type: String,
  42. default: ''
  43. }
  44. },
  45. computed: {
  46. rootClass() {
  47. const cls = {
  48. 'cube-popup_mask': this.mask
  49. }
  50. if (this.type) {
  51. cls[`cube-${this.type}`] = true
  52. }
  53. return cls
  54. },
  55. containerClass() {
  56. const center = this.center
  57. const position = this.position
  58. if (position) {
  59. return {
  60. [`cube-popup-${position}`]: true
  61. }
  62. }
  63. if (center) {
  64. return {
  65. 'cube-popup-center': true
  66. }
  67. }
  68. }
  69. },
  70. methods: {
  71. maskClick(e) {
  72. this.$emit(EVENT_MASK_CLICK, e)
  73. if (this.maskClosable) {
  74. this.hide()
  75. }
  76. }
  77. }
  78. }
  79. </script>
  80. <style lang="stylus" rel="stylesheet/stylus">
  81. @require "../../common/stylus/variable.styl"
  82. .cube-popup
  83. position: fixed
  84. left: 0
  85. right:0
  86. top: 0
  87. bottom: 0
  88. z-index: 100
  89. pointer-events: none
  90. .cube-popup_mask
  91. pointer-events: auto
  92. .cube-popup-mask
  93. display: block
  94. .cube-popup-mask, .cube-popup-container
  95. position: absolute
  96. width: 100%
  97. height: 100%
  98. .cube-popup-mask
  99. display: none
  100. overflow: hidden
  101. background-color: $popup-mask-bgc
  102. opacity: $popup-mask-opacity
  103. pointer-events: auto
  104. // fix some android webview opacity render bug
  105. &::before
  106. content: "."
  107. display: block
  108. width: 1px
  109. height: 1px
  110. background-color: rgba(0, 0, 0, .1)
  111. margin-left: -10px
  112. .cube-popup-container
  113. transform: translate(100%, 100%)
  114. .cube-popup-content
  115. position: absolute
  116. top: 0
  117. left: 0
  118. width: 100%
  119. box-sizing: border-box
  120. transform: translate(-100%, -100%)
  121. pointer-events: auto
  122. .cube-popup-center,
  123. .cube-popup-right,
  124. .cube-popup-left
  125. .cube-popup-content
  126. top: -50%
  127. left: -50%
  128. width: auto
  129. max-width: 100%
  130. transform: translate(0, 0)
  131. .cube-popup-right,
  132. .cube-popup-left
  133. .cube-popup-content
  134. height: 100%
  135. top: -100%
  136. .cube-popup-center
  137. .cube-popup-content
  138. transform: translate(-50%, -50%)
  139. .cube-popup-top
  140. .cube-popup-content
  141. top: -100%
  142. left: -100%
  143. transform: translate(0, 0)
  144. .cube-popup-right
  145. .cube-popup-content
  146. top: -100%
  147. right: 100%
  148. .cube-popup-left
  149. .cube-popup-content
  150. left: -100%
  151. </style>