| <template> | 
|     <div class="preview"> | 
|         <div class="preview_close" @click="closes"> | 
|             <van-icon name="cross" size="20" /> | 
|         </div> | 
|         <div class="preview_content"> | 
|             <Swiper @slideChange="onSlideChange" :initialSlide="props.index"> | 
|                 <SwiperSlide v-for="(item, index) in props.list" :key="index"> | 
|                     <div class="preview_content_box"> | 
|                         <img v-if="item.type === 0" :src="item.url" alt="" /> | 
|                         <video ref="video" v-else-if="item.type === 1" :src="item.url" controls="controls"></video> | 
|                     </div> | 
|                 </SwiperSlide> | 
|             </Swiper> | 
|         </div> | 
|     </div> | 
| </template> | 
|   | 
| <script setup lang="ts"> | 
|     import { ref, defineProps, defineEmits } from 'vue' | 
|     import { Swiper, SwiperSlide } from 'swiper/vue' | 
|     import 'swiper/css' | 
|     import 'swiper/css/effect-cube' | 
|     import 'swiper/css/pagination' | 
|   | 
|     const props = defineProps({ | 
|         list: { | 
|             type: Array, | 
|             require: true | 
|         }, | 
|         index: { | 
|             type: Number, | 
|             default: 0 | 
|         } | 
|     }) | 
|   | 
|     let video: any = ref(null) | 
|   | 
|     const emit = defineEmits([ 'close' ]) | 
|   | 
|     // 关闭组件 | 
|     const closes = () => { | 
|         emit('close') | 
|     } | 
|   | 
|     // 切换暂停播放 | 
|     const onSlideChange = () => { | 
|         if (!video.value) return | 
|         video.value.forEach((item: any) => { | 
|             item.pause() | 
|         }) | 
|     } | 
| </script> | 
|   | 
| <style lang="scss" scoped> | 
| .preview { | 
|     position: fixed; | 
|     top: 0; | 
|     left: 0; | 
|     width: 100%; | 
|     height: 100%; | 
|     background: rgba(0, 0, 0, 0.8); | 
|     z-index: 9999; | 
|     .preview_close { | 
|         position: fixed; | 
|         right: 50px; | 
|         top: 50px; | 
|         width: 70px; | 
|         height: 70px; | 
|         border-radius: 50%; | 
|         background: #B2B2B2; | 
|         display: flex; | 
|         align-items: center; | 
|         justify-content: center; | 
|         z-index: 99999; | 
|     } | 
|     .preview_content { | 
|         height: 100%; | 
|         position: relative; | 
|         top: 50%; | 
|         left: 0; | 
|         transform: translate(0, -50%); | 
|         .swiper { | 
|             width: 100%; | 
|             height: 100%; | 
|             display: flex; | 
|             align-items: center; | 
|             justify-content: center; | 
|             .swiper-slide { | 
|                 width: 100%; | 
|                 height: 100%; | 
|                 position: relative; | 
|                 .preview_content_box { | 
|                     width: 100%; | 
|                     position: absolute; | 
|                     top: 50%; | 
|                     left: 50%; | 
|                     transform: translate(-50%, -50%); | 
|                     display: flex; | 
|                     align-items: center; | 
|                     justify-content: center; | 
|                     img { | 
|                         width: 100%; | 
|                     } | 
|                     video { | 
|                         width: 100%; | 
|                     } | 
|                 } | 
|             } | 
|         } | 
|     } | 
| } | 
| </style> |