uni-popup.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <template>
  2. <view>
  3. <view v-show="show"
  4. :style="{ top: offsetTop + 'px' }"
  5. class="uni-mask"
  6. @click="hide"
  7. @touchmove.stop.prevent="moveHandle" />
  8. <view v-show="show"
  9. :class="'uni-popup-' + position + ' ' + 'uni-popup-' + mode"
  10. class="uni-popup">
  11. {{ msg }}
  12. <slot />
  13. <view v-if="position === 'middle' && mode === 'insert'"
  14. :class="{
  15. 'uni-close-bottom': buttonMode === 'bottom',
  16. 'uni-close-right': buttonMode === 'right'
  17. }"
  18. class=" uni-icon uni-icon-close"
  19. @click="closeMask" />
  20. </view>
  21. </view>
  22. </template>
  23. <script>
  24. export default {
  25. name: 'UniPopup',
  26. props: {
  27. /**
  28. * 页面显示
  29. */
  30. show: {
  31. type: Boolean,
  32. default: false
  33. },
  34. /**
  35. * 对齐方式
  36. */
  37. position: {
  38. type: String,
  39. // top - 顶部, middle - 居中, bottom - 底部
  40. default: 'middle'
  41. },
  42. /**
  43. * 显示模式
  44. */
  45. mode: {
  46. type: String,
  47. default: 'insert'
  48. },
  49. /**
  50. * 额外信息
  51. */
  52. msg: {
  53. type: String,
  54. default: ''
  55. },
  56. /**
  57. * h5遮罩是否到顶
  58. */
  59. h5Top: {
  60. type: Boolean,
  61. default: false
  62. },
  63. buttonMode: {
  64. type: String,
  65. default: 'bottom'
  66. }
  67. },
  68. data () {
  69. return {
  70. offsetTop: 0
  71. }
  72. },
  73. watch: {
  74. h5Top (newVal) {
  75. if (newVal) {
  76. this.offsetTop = 44
  77. } else {
  78. this.offsetTop = 0
  79. }
  80. }
  81. },
  82. created () {
  83. let offsetTop = 0
  84. // #ifdef H5
  85. if (!this.h5Top) {
  86. offsetTop = 44
  87. } else {
  88. offsetTop = 0
  89. }
  90. // #endif
  91. this.offsetTop = offsetTop
  92. },
  93. methods: {
  94. hide () {
  95. if (this.mode === 'insert' && this.position === 'middle') return
  96. this.$emit('hidePopup')
  97. },
  98. closeMask () {
  99. if (this.mode === 'insert') {
  100. this.$emit('hidePopup')
  101. }
  102. },
  103. moveHandle () { }
  104. }
  105. }
  106. </script>
  107. <style>
  108. .uni-mask {
  109. position: fixed;
  110. z-index: 998;
  111. top: 0;
  112. right: 0;
  113. bottom: 0;
  114. left: 0;
  115. background-color: rgba(0, 0, 0, 0.3);
  116. }
  117. .uni-popup {
  118. position: absolute;
  119. z-index: 999;
  120. background-color: #ffffff;
  121. }
  122. .uni-popup-middle {
  123. display: flex;
  124. flex-direction: column;
  125. align-items: center;
  126. justify-content: center;
  127. top: 50%;
  128. left: 50%;
  129. transform: translate(-50%, -50%);
  130. }
  131. .uni-popup-middle.uni-popup-insert {
  132. min-width: 380upx;
  133. min-height: 380upx;
  134. max-width: 100%;
  135. max-height: 80%;
  136. transform: translate(-50%, -65%);
  137. background: none;
  138. box-shadow: none;
  139. }
  140. .uni-popup-middle.uni-popup-fixed {
  141. border-radius: 10upx;
  142. padding: 30upx;
  143. }
  144. .uni-close-bottom,
  145. .uni-close-right {
  146. position: absolute;
  147. bottom: -180upx;
  148. text-align: center;
  149. border-radius: 50%;
  150. color: #f5f5f5;
  151. font-size: 60upx;
  152. font-weight: bold;
  153. opacity: 0.8;
  154. z-index: -1;
  155. }
  156. .uni-close-bottom {
  157. margin: auto;
  158. left: 0;
  159. right: 0;
  160. }
  161. .uni-close-right {
  162. right: -60upx;
  163. top: -80upx;
  164. }
  165. .uni-close-bottom:after {
  166. content: "";
  167. position: absolute;
  168. width: 0px;
  169. border: 1px #f5f5f5 solid;
  170. top: -200upx;
  171. bottom: 56upx;
  172. left: 50%;
  173. transform: translate(-50%, -0%);
  174. opacity: 0.8;
  175. }
  176. .uni-popup-top {
  177. top: 0;
  178. left: 0;
  179. width: 100%;
  180. height: 100upx;
  181. line-height: 100upx;
  182. text-align: center;
  183. }
  184. .uni-popup-bottom {
  185. left: 0;
  186. bottom: 0;
  187. width: 100%;
  188. min-height: 100upx;
  189. line-height: 100upx;
  190. text-align: center;
  191. }
  192. </style>