|
|
- <template>
- <view class="show-example" v-if="show">
- <!-- 遮罩层 -->
- <view
- class="mask"
- :class="{ active: show }"
- @click="closeModal"
- ></view>
-
- <!-- 弹窗内容 -->
- <view class="modal" :class="{ active: show }">
- <view class="modal-header">
- <view class="modal-title">查看示例</view>
- <view class="close-btn" @click="closeModal">
- 关闭
- </view>
- </view>
-
- <view class="modal-content">
- <view v-if="loading" class="loading-area">
- <view class="loading-text">加载中...</view>
- </view>
-
- <view v-if="url && !loading && !error" class="image-area">
- <image
- class="example-image"
- :src="url"
- mode="widthFix"
- @load="onImageLoad"
- @error="onImageError"
- />
- </view>
-
- <view v-if="error" class="error-area">
- <view class="error-text">图片加载失败</view>
- </view>
- </view>
- </view>
- </view>
- </template>
-
- <script>
- export default {
- name: 'ShowExample',
- props: {
- show: {
- type: Boolean,
- default: false
- },
- url: {
- type: String,
- default: ''
- }
- },
- data() {
- return {
- loading: false,
- error: false
- }
- },
- watch: {
- show(newVal) {
- if (newVal && this.url) {
- this.loading = true;
- this.error = false;
- }
- },
- url(newVal) {
- if (newVal && this.show) {
- this.loading = true;
- this.error = false;
- }
- }
- },
- methods: {
- // 关闭弹窗
- closeModal() {
- this.$emit('close');
- },
-
- // 图片加载成功
- onImageLoad() {
- this.loading = false;
- this.error = false;
- },
-
- // 图片加载失败
- onImageError() {
- this.loading = false;
- this.error = true;
- }
- }
- }
- </script>
-
- <style scoped lang="scss">
- .show-example {
- position: relative;
- }
-
- .mask {
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- background-color: rgba(0, 0, 0, 0.5);
- z-index: 1000;
- opacity: 0;
- visibility: hidden;
- transition: all 0.3s ease;
-
- &.active {
- opacity: 1;
- visibility: visible;
- }
- }
-
- .modal {
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%) scale(0.8);
- width: 90vw;
- max-width: 600rpx;
- max-height: 80vh;
- background-color: #fff;
- border-radius: 20rpx;
- z-index: 1001;
- opacity: 0;
- visibility: hidden;
- transition: all 0.3s ease;
- overflow: hidden;
-
- &.active {
- opacity: 1;
- visibility: visible;
- transform: translate(-50%, -50%) scale(1);
- }
- }
-
- .modal-header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 30rpx;
- border-bottom: 1rpx solid #eee;
- }
-
- .modal-title {
- font-size: 32rpx;
- font-weight: bold;
- color: #333;
- }
-
- .close-btn {
- padding: 10rpx 20rpx;
- background-color: #f5f5f5;
- border-radius: 10rpx;
- font-size: 28rpx;
- color: #666;
- }
-
- .modal-content {
- padding: 30rpx;
- max-height: 60vh;
- overflow-y: auto;
- }
-
- .loading-area {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 200rpx;
- }
-
- .loading-text {
- font-size: 28rpx;
- color: #666;
- }
-
- .image-area {
- width: 100%;
- text-align: center;
- }
-
- .example-image {
- width: 100%;
- max-width: 100%;
- border-radius: 10rpx;
- }
-
- .error-area {
- display: flex;
- justify-content: center;
- align-items: center;
- height: 200rpx;
- }
-
- .error-text {
- font-size: 28rpx;
- color: #ff4757;
- }
- </style>
|