Files
gterFang/src/components/detail/imageWatch.vue
2024-08-26 11:09:15 +08:00

277 lines
6.8 KiB
Vue

<template>
<div class="watch-box" v-show="show">
<div class="pos-r dis-f al-item jus-x mg-t-60">
<div class="carousel-w">
<el-carousel arrow="never" height="600px" :autoplay="false" :initial-index="props.index" indicator-position="none" ref="carousel" @change="carouselChange">
<el-carousel-item v-for="(item, i) in list" :key="i">
<div class="dis-f jus-x al-item" v-if="item">
<div class="img-box dis-f jus-x" v-if="item['type'] != 'attachment'">
<video v-if="i >= imageTab - 1 && i <= imageTab + 1" :autoplay="false" controls :src="item.url || item['videourl']" :preload="imageTab == i ? 'metadata' : 'none'" style="width: 800px;"></video>
</div>
<div class="img-box dis-f jus-x" v-else>
<img v-if="i >= imageTab - 1 && i <= imageTab + 1" :src="(item && item.url) || item['imageurl'] || item['image']" class="img" alt="" />
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<img src="../../assets/img/detail/imageArrowIcon.svg" class="image-arrow-icon left-arrow" @click="prev" alt="" />
<img src="../../assets/img/detail/imageArrowIcon.svg" class="image-arrow-icon right-arrow" @click="next" alt="" />
</div>
<div class="tab-text">{{ `${imageTab + 1}/${list.length}` }}</div>
<div class="dis-f jus-x al-item">
<div class="list-img-box dis-f al-item jus-x">
<div v-for="(item, i) in list" :key="i" @click="watchSet(i)" class="pos-r" style="margin-bottom: 10px;">
<div class="voide" :class="{ 'select-box': imageTab === i }" v-if="item['type'] != 'attachment'">
<div class="icon-box dis-f jus-x al-item" :class="{ 'bor-r-8': imageTab === i }">
<img src="../../assets/img/detail/videoStop.svg" class="icon" alt="" />
</div>
</div>
<div class="img-box-s dis-f jus-x" :class="[{ 'select-box': imageTab === i && item.thumbnail }, { 'voide-img': !item.thumbnail }]">
<img v-lazy="item.thumbnail || item.image" alt="" class="img-s" style="object-fit: cover;" />
</div>
</div>
</div>
</div>
<img src="../../assets/img/detail/imageClose.svg" @click="close" class="close-img" alt="" />
</div>
</template>
<script setup>
import { reactive, onMounted, ref, defineProps, watchEffect, watch } from "vue"
// type 的类型代表 attachment 图片 videos 视频 lives 直播
const props = defineProps({
//url:展示图 thumbnail:缩略图
// list:[{url:'',thumbnail:''}]
list: {
type: Array,
default: function () {
return []
},
},
index: {
type: Number,
default: function () {
return 0
},
},
close: {
type: Function,
},
show: {
type: Boolean,
default: false,
},
})
let show = props.show
let list = ref([])
let close = props.close
let carousel = ref(null)
let imageTab = ref(0)
//上一张
let prev = () => carousel.value.prev()
// 轮播图滚动后事件
const carouselChange = value => {
console.log("value")
imageTab.value = value
}
//下一张
let next = () => carousel.value.next()
//点击预览图
let watchSet = num => {
carousel.value.setActiveItem(num)
}
onMounted(() => {
watchEffect(() => {
show = props.show
list.value = props.list
// carousel.value.setActiveItem(props.index)
})
})
watch(
() => props.index,
(newValue, oldValue) => {
imageTab.value = newValue
watchSet(imageTab.value)
}
)
</script>
<style scoped lang="less">
img {
object-fit: contain;
}
.dis-f {
display: flex;
}
.jus-x {
justify-content: center;
}
.al-item {
align-items: center;
}
.pos-r {
position: relative;
}
.body-maxWidth {
width: 1200px;
min-width: 1200px;
}
.s-w-100 {
width: 100%;
}
.jus-bet {
justify-content: space-between;
}
.close-img {
width: 20px;
height: 20px;
position: absolute;
right: 20px;
top: 20px;
cursor: pointer;
}
.right-arrow {
right: 30px;
z-index: 66;
}
.left-arrow {
left: 30px;
z-index: 66;
transform: rotate(180deg);
}
.image-arrow-icon {
width: 18px;
height: 30px;
position: absolute;
cursor: pointer;
}
.mg-t-60 {
margin-top: 60px;
}
.select-box {
border: 1px solid #50e3c2 !important;
}
.carousel-w {
min-width: 800px;
}
.watch-box {
width: 100%;
height: 100%;
background: #4c4c4c;
position: fixed;
top: 0;
left: 0;
z-index: 1003;
.tab-text {
font-family: "PingFangSC-Regular", "PingFang SC", sans-serif;
font-weight: 400;
font-style: normal;
font-size: 14px;
color: #ffffff;
text-align: center;
padding: 20px 0;
}
.list-img-box {
overflow-x: scroll;
width: 1200px;
flex-wrap: wrap;
/* height: 100px; */
.img-box-s {
height: 62px;
border: 1px solid transparent;
border-radius: 8px;
margin-left: 5px;
cursor: pointer;
object-fit: cover;
.img-s {
height: 60px;
border-radius: 8px;
}
}
.voide-img {
width: 60px;
height: 60px;
border: 1px solid transparent;
margin-left: 5px;
border-radius: 8px;
cursor: pointer;
overflow: hidden;
}
.voide {
width: calc(100% - 5px);
height: 100%;
border: 1px solid transparent;
margin-left: 5px;
border-radius: 8px;
cursor: pointer;
position: absolute;
top: 0;
left: 0;
.bor-r-8 {
border-radius: 8px !important;
}
.icon-box {
width: 100%;
height: 100%;
background: inherit;
background-color: rgba(51, 51, 51, 0.733333333333333);
border: none;
border-radius: 6px;
.icon {
width: 18px;
height: 18px;
}
}
}
}
.img-box {
width: 800px;
height: 600px;
border-radius: 10px;
overflow: hidden;
.img {
width: 800px;
height: 600px;
}
}
}
::-webkit-scrollbar {
display: none;
}
</style>