混凝土运输管理微信小程序、替班
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.

203 lines
3.3 KiB

2 weeks ago
  1. <template>
  2. <view class="show-example" v-if="show">
  3. <!-- 遮罩层 -->
  4. <view
  5. class="mask"
  6. :class="{ active: show }"
  7. @click="closeModal"
  8. ></view>
  9. <!-- 弹窗内容 -->
  10. <view class="modal" :class="{ active: show }">
  11. <view class="modal-header">
  12. <view class="modal-title">查看示例</view>
  13. <view class="close-btn" @click="closeModal">
  14. 关闭
  15. </view>
  16. </view>
  17. <view class="modal-content">
  18. <view v-if="loading" class="loading-area">
  19. <view class="loading-text">加载中...</view>
  20. </view>
  21. <view v-if="url && !loading && !error" class="image-area">
  22. <image
  23. class="example-image"
  24. :src="url"
  25. mode="widthFix"
  26. @load="onImageLoad"
  27. @error="onImageError"
  28. />
  29. </view>
  30. <view v-if="error" class="error-area">
  31. <view class="error-text">图片加载失败</view>
  32. </view>
  33. </view>
  34. </view>
  35. </view>
  36. </template>
  37. <script>
  38. export default {
  39. name: 'ShowExample',
  40. props: {
  41. show: {
  42. type: Boolean,
  43. default: false
  44. },
  45. url: {
  46. type: String,
  47. default: ''
  48. }
  49. },
  50. data() {
  51. return {
  52. loading: false,
  53. error: false
  54. }
  55. },
  56. watch: {
  57. show(newVal) {
  58. if (newVal && this.url) {
  59. this.loading = true;
  60. this.error = false;
  61. }
  62. },
  63. url(newVal) {
  64. if (newVal && this.show) {
  65. this.loading = true;
  66. this.error = false;
  67. }
  68. }
  69. },
  70. methods: {
  71. // 关闭弹窗
  72. closeModal() {
  73. this.$emit('close');
  74. },
  75. // 图片加载成功
  76. onImageLoad() {
  77. this.loading = false;
  78. this.error = false;
  79. },
  80. // 图片加载失败
  81. onImageError() {
  82. this.loading = false;
  83. this.error = true;
  84. }
  85. }
  86. }
  87. </script>
  88. <style scoped lang="scss">
  89. .show-example {
  90. position: relative;
  91. }
  92. .mask {
  93. position: fixed;
  94. top: 0;
  95. left: 0;
  96. width: 100vw;
  97. height: 100vh;
  98. background-color: rgba(0, 0, 0, 0.5);
  99. z-index: 1000;
  100. opacity: 0;
  101. visibility: hidden;
  102. transition: all 0.3s ease;
  103. &.active {
  104. opacity: 1;
  105. visibility: visible;
  106. }
  107. }
  108. .modal {
  109. position: fixed;
  110. top: 50%;
  111. left: 50%;
  112. transform: translate(-50%, -50%) scale(0.8);
  113. width: 90vw;
  114. max-width: 600rpx;
  115. max-height: 80vh;
  116. background-color: #fff;
  117. border-radius: 20rpx;
  118. z-index: 1001;
  119. opacity: 0;
  120. visibility: hidden;
  121. transition: all 0.3s ease;
  122. overflow: hidden;
  123. &.active {
  124. opacity: 1;
  125. visibility: visible;
  126. transform: translate(-50%, -50%) scale(1);
  127. }
  128. }
  129. .modal-header {
  130. display: flex;
  131. justify-content: space-between;
  132. align-items: center;
  133. padding: 30rpx;
  134. border-bottom: 1rpx solid #eee;
  135. }
  136. .modal-title {
  137. font-size: 32rpx;
  138. font-weight: bold;
  139. color: #333;
  140. }
  141. .close-btn {
  142. padding: 10rpx 20rpx;
  143. background-color: #f5f5f5;
  144. border-radius: 10rpx;
  145. font-size: 28rpx;
  146. color: #666;
  147. }
  148. .modal-content {
  149. padding: 30rpx;
  150. max-height: 60vh;
  151. overflow-y: auto;
  152. }
  153. .loading-area {
  154. display: flex;
  155. justify-content: center;
  156. align-items: center;
  157. height: 200rpx;
  158. }
  159. .loading-text {
  160. font-size: 28rpx;
  161. color: #666;
  162. }
  163. .image-area {
  164. width: 100%;
  165. text-align: center;
  166. }
  167. .example-image {
  168. width: 100%;
  169. max-width: 100%;
  170. border-radius: 10rpx;
  171. }
  172. .error-area {
  173. display: flex;
  174. justify-content: center;
  175. align-items: center;
  176. height: 200rpx;
  177. }
  178. .error-text {
  179. font-size: 28rpx;
  180. color: #ff4757;
  181. }
  182. </style>