uni-popup.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <view v-if="showPopup" class="uni-popup" :style="{'z-index': zIndex}">
  3. <view :class="[ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__mask" @click="close(true)" />
  4. <view :class="[type, ani, animation ? 'ani' : '', !custom ? 'uni-custom' : '']" class="uni-popup__wrapper" @click="close(true)">
  5. <view :class="['uni-popup__wrapper-box', isRadius?'uni-popup__wrapper-radius':'']" @click.stop="clear" :style="{'maxHeight': maxHeight,'width': width}">
  6. <slot />
  7. </view>
  8. </view>
  9. </view>
  10. </template>
  11. <script>
  12. export default {
  13. name: 'UniPopup',
  14. props: {
  15. // 开启动画
  16. animation: {
  17. type: Boolean,
  18. default: true
  19. },
  20. // 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
  21. type: {
  22. type: String,
  23. default: 'center'
  24. },
  25. // 是否开启自定义
  26. custom: {
  27. type: Boolean,
  28. default: false
  29. },
  30. // maskClick
  31. maskClick: {
  32. type: Boolean,
  33. default: true
  34. },
  35. show: {
  36. type: Boolean,
  37. default: true
  38. },
  39. // 最大高度,以rpx为单位
  40. maxHeight: {
  41. type: String,
  42. default: '500rpx'
  43. },
  44. // 定义宽度
  45. width: {
  46. type: String,
  47. default: '80%'
  48. },
  49. zIndex: {
  50. type: Number,
  51. default: 99999
  52. },
  53. isRadius: {
  54. type: Boolean,
  55. default: false
  56. }
  57. },
  58. data() {
  59. return {
  60. ani: '',
  61. showPopup: false
  62. }
  63. },
  64. watch: {
  65. show(newValue) {
  66. if (newValue) {
  67. this.open()
  68. } else {
  69. this.close()
  70. }
  71. }
  72. },
  73. created() {},
  74. methods: {
  75. clear() {},
  76. open() {
  77. this.$emit('change', {
  78. show: true
  79. })
  80. this.showPopup = true
  81. this.$nextTick(() => {
  82. this.ani = 'uni-' + this.type
  83. })
  84. },
  85. close(type) {
  86. if (!this.maskClick && type) return
  87. this.$emit('change', {
  88. show: false
  89. })
  90. this.ani = ''
  91. this.$emit('update:show', false)
  92. this.$nextTick(() => {
  93. this.showPopup = false
  94. })
  95. }
  96. }
  97. }
  98. </script>
  99. <style lang="scss">
  100. .uni-popup {
  101. position: fixed;
  102. /* #ifdef H5 */
  103. top: 0px;
  104. // top: 50px;
  105. /* #endif */
  106. /* #ifndef H5 */
  107. top: 0px;
  108. /* #endif */
  109. bottom: 0;
  110. left: 0;
  111. right: 0;
  112. z-index: 9999;
  113. overflow: hidden;
  114. &__mask {
  115. position: absolute;
  116. top: 0;
  117. bottom: 0;
  118. left: 0;
  119. right: 0;
  120. z-index: 998;
  121. background: rgba(0, 0, 0, 0.4);
  122. opacity: 0;
  123. &.ani {
  124. transition: all 0.3s;
  125. }
  126. &.uni-top,
  127. &.uni-bottom,
  128. &.uni-center {
  129. opacity: 1;
  130. }
  131. }
  132. &__wrapper {
  133. position: absolute;
  134. z-index: 999;
  135. box-sizing: border-box;
  136. &.ani {
  137. transition: all 0.3s;
  138. }
  139. &.top {
  140. top: 0;
  141. left: 0;
  142. width: 100%;
  143. transform: translateY(-100%);
  144. }
  145. &.bottom {
  146. bottom: 0;
  147. left: 0;
  148. width: 100%;
  149. transform: translateY(100%);
  150. }
  151. &.center {
  152. width: 100%;
  153. height: 100%;
  154. display: flex;
  155. justify-content: center;
  156. align-items: center;
  157. transform: scale(1.2);
  158. opacity: 0;
  159. }
  160. &-radius {
  161. border-radius: 20px;
  162. }
  163. &-box {
  164. position: relative;
  165. box-sizing: border-box;
  166. }
  167. &.uni-custom {
  168. // & .uni-popup__wrapper-box {
  169. // padding: 30upx;
  170. // background-color: inherit;
  171. // }
  172. &.center {
  173. & .uni-popup__wrapper-box {
  174. position: relative;
  175. max-width: 90%;
  176. max-height: 90%;
  177. }
  178. }
  179. &.top,
  180. &.bottom {
  181. & .uni-popup__wrapper-box {
  182. width: 100%;
  183. overflow-y: scroll;
  184. border-top-left-radius: 30upx;
  185. border-top-right-radius: 30upx;
  186. }
  187. }
  188. }
  189. &.uni-top,
  190. &.uni-bottom {
  191. transform: translateY(0);
  192. }
  193. &.uni-center {
  194. transform: scale(1);
  195. opacity: 1;
  196. }
  197. }
  198. }
  199. </style>