CustomDialog.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <template>
  2. <view class="custom-dialog" v-if="visible">
  3. <view class="dialog-mask" @click="closeDialog"></view>
  4. <view class="dialog-content" :class="{'dialog-show': visible}" :animation="animationData">
  5. <view class="dialog-header">
  6. <text class="dialog-title">{{title}}</text>
  7. <view class="dialog-close" @click="closeDialog">×</view>
  8. </view>
  9. <view class="dialog-body">
  10. <slot></slot>
  11. </view>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. export default {
  17. name: 'CustomDialog',
  18. props: {
  19. visible: {
  20. type: Boolean,
  21. default: false
  22. },
  23. title: {
  24. type: String,
  25. default: '提示'
  26. }
  27. },
  28. data() {
  29. return {
  30. animationData: {}
  31. }
  32. },
  33. watch: {
  34. visible(val) {
  35. if (val) {
  36. this.playShowAnimation()
  37. } else {
  38. this.playHideAnimation()
  39. }
  40. }
  41. },
  42. methods: {
  43. playShowAnimation() {
  44. const animation = uni.createAnimation({
  45. duration: 300,
  46. timingFunction: 'ease'
  47. })
  48. animation.scale(0.8).opacity(0).step({ duration: 0 })
  49. animation.scale(1.1).opacity(1).step({ duration: 150 })
  50. animation.scale(0.95).step({ duration: 75 })
  51. animation.scale(1).step({ duration: 75 })
  52. this.animationData = animation.export()
  53. },
  54. playHideAnimation() {
  55. const animation = uni.createAnimation({
  56. duration: 200,
  57. timingFunction: 'ease'
  58. })
  59. animation.scale(0.95).opacity(0.8).step({ duration: 100 })
  60. animation.scale(0.8).opacity(0).step({ duration: 100 })
  61. this.animationData = animation.export()
  62. },
  63. closeDialog() {
  64. this.$emit('update:visible', false)
  65. this.$emit('close')
  66. }
  67. }
  68. }
  69. </script>
  70. <style lang="scss" scoped>
  71. .custom-dialog {
  72. position: fixed;
  73. top: 0;
  74. left: 0;
  75. right: 0;
  76. bottom: 0;
  77. z-index: 9999;
  78. display: flex;
  79. align-items: center;
  80. justify-content: center;
  81. .dialog-mask {
  82. position: absolute;
  83. top: 0;
  84. left: 0;
  85. right: 0;
  86. bottom: 0;
  87. background: rgba(0, 0, 0, 0.6);
  88. }
  89. .dialog-content {
  90. position: relative;
  91. width: 600rpx;
  92. background: #fff;
  93. border-radius: 16rpx;
  94. overflow: hidden;
  95. opacity: 0;
  96. transform: scale(0.8);
  97. &.dialog-show {
  98. opacity: 1;
  99. transform: scale(1);
  100. }
  101. }
  102. .dialog-header {
  103. position: relative;
  104. padding: 30rpx;
  105. text-align: center;
  106. border-bottom: 1rpx solid #eee;
  107. .dialog-title {
  108. font-size: 32rpx;
  109. font-weight: 500;
  110. color: #333;
  111. }
  112. .dialog-close {
  113. position: absolute;
  114. right: 20rpx;
  115. top: 50%;
  116. transform: translateY(-50%);
  117. width: 60rpx;
  118. height: 60rpx;
  119. line-height: 60rpx;
  120. text-align: center;
  121. font-size: 40rpx;
  122. color: #999;
  123. cursor: pointer;
  124. &:active {
  125. opacity: 0.7;
  126. }
  127. }
  128. }
  129. .dialog-body {
  130. padding: 30rpx;
  131. }
  132. }
  133. </style>