木邻有你前端代码仓库
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

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months 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>