木邻有你前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

186 lines
4.7 KiB

3 months ago
  1. <template>
  2. <!-- 如何让他点击遮罩层的时候关闭弹窗 -->
  3. <view v-if="visible" class="popup-overlay" @click="close">
  4. <view class="popup-content" @click.stop :animation="animationData" :style="{backgroundImage: `${bgImage}`}">
  5. <image class="popup-title" :src="titleImage" mode="aspectFit"></image>
  6. <!-- <view class="popup-header"> -->
  7. <text class="popup-text">{{ content }}</text>
  8. <text class="popup-subtext">{{ subContent }}</text>
  9. <!-- </view> -->
  10. <button v-if="popupType === 'success'" class="popup-btn success" @click="close">我知道了</button>
  11. <button v-else class="popup-btn fail" @click="close">好的</button>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: 'GlobalPopup',
  18. data() {
  19. return {
  20. visible: false,
  21. content: '',
  22. subContent: '',
  23. titleType: '',
  24. popupType: '',
  25. animationData: {}
  26. }
  27. },
  28. computed: {
  29. bgImage() {
  30. return `url(${this.popupType === 'success' ? '/static/成功弹窗.png' : '/static/失败弹窗.png'})`
  31. },
  32. titleImage() {
  33. switch (this.titleType) {
  34. case 'exchange':
  35. if (this.popupType === 'success') {
  36. return '/static/兑换成功.png'
  37. }else{
  38. return '/static/兑换失败.png'
  39. }
  40. case 'signup':
  41. return '/static/报名成功.png'
  42. case 'submit':
  43. return '/static/提交成功.png'
  44. default:
  45. return ''
  46. }
  47. }
  48. },
  49. methods: {
  50. close() {
  51. this.createHideAnimation()
  52. },
  53. // 主内容 副内容 标题类型 弹窗类型
  54. open({
  55. content = '默认内容',
  56. subContent = '默认子内容',
  57. titleType = 'exchange', // 报名 兑换 提交
  58. popupType = 'success' // 成功 失败
  59. }) {
  60. this.content = content
  61. this.subContent = subContent
  62. this.titleType = titleType
  63. this.popupType = popupType
  64. // 先设置初始动画状态
  65. this.setInitialAnimation()
  66. // 显示弹窗
  67. this.visible = true
  68. // 延迟执行显示动画
  69. this.$nextTick(() => {
  70. setTimeout(() => {
  71. this.createShowAnimation()
  72. }, 50)
  73. })
  74. },
  75. // 设置初始动画状态
  76. setInitialAnimation() {
  77. const animation = uni.createAnimation({
  78. transformOrigin: "50% 50%",
  79. duration: 0,
  80. timingFunction: "ease-out",
  81. delay: 0
  82. })
  83. animation.translateX('-50%').translateY('-50%').scale(0).opacity(0).step()
  84. this.animationData = animation.export()
  85. },
  86. // 创建弹窗显示动画
  87. createShowAnimation() {
  88. const animation = uni.createAnimation({
  89. transformOrigin: "50% 50%",
  90. duration: 200,
  91. timingFunction: "ease-out",
  92. delay: 0
  93. })
  94. // 动画到最终状态:保持居中,缩放为1,透明度为1
  95. animation.translateX('-50%').translateY('-50%').scale(1).opacity(1).step()
  96. this.animationData = animation.export()
  97. },
  98. // 创建弹窗隐藏动画
  99. createHideAnimation() {
  100. const animation = uni.createAnimation({
  101. transformOrigin: "50% 50%",
  102. duration: 200,
  103. timingFunction: "ease-in",
  104. delay: 0
  105. })
  106. animation.translateX('-50%').translateY('-50%').scale(0).opacity(0).step()
  107. this.animationData = animation.export()
  108. // 动画结束后隐藏弹窗
  109. setTimeout(() => {
  110. this.visible = false
  111. }, 200)
  112. }
  113. }
  114. }
  115. </script>
  116. <style scoped lang="scss">
  117. .popup-overlay {
  118. position: fixed;
  119. inset: 0;
  120. width: 100%;
  121. height: 100%;
  122. background: #00000050;
  123. z-index: 999;
  124. .popup-content {
  125. position: absolute;
  126. top: 50%;
  127. left: 50%;
  128. width: 632rpx;
  129. padding: 0;
  130. height: 830rpx;
  131. // background: red;
  132. // border-radius: 20rpx;
  133. background-size: 100% 100%;
  134. .popup-title{
  135. position: absolute;
  136. top: 44rpx;
  137. left: 88rpx;
  138. height: 100rpx;
  139. width: 254rpx;
  140. }
  141. .popup-btn{
  142. position: absolute;
  143. bottom: 30rpx;
  144. left: 50%;
  145. transform: translateX(-50%);
  146. width: 432rpx;
  147. height: 94rpx;
  148. border-radius: 20.5px;
  149. // width: 28px;
  150. font-size: 14px;
  151. line-height: 94rpx;
  152. color: #ffffff;
  153. }
  154. .success{
  155. background: #1488db;
  156. }
  157. .fail{
  158. background: #e54b4b;
  159. }
  160. .popup-text{
  161. font-size: 16px;
  162. position: absolute;
  163. top: 480rpx;
  164. left: 50%;
  165. transform: translateX(-50%);
  166. font-weight: 700;
  167. color: #000000;
  168. white-space: nowrap;
  169. // text-align: center;
  170. }
  171. .popup-subtext{
  172. position: absolute;
  173. bottom: 252rpx;
  174. left: 50%;
  175. transform: translateX(-50%);
  176. font-size: 14px;
  177. color: #999999;
  178. white-space: nowrap;
  179. // text-align: center;
  180. }
  181. }
  182. }
  183. </style>