展品维保小程序前端代码接口
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.

198 lines
5.0 KiB

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