效果
组件
<template>
<div class="goods-imgs">
<div class="imgs-show">
<img :src="mainImage" alt="大图" />
</div>
<ul class="img-thumbnail">
<li v-for="(item, index) in imageList" :key="index" class="img-li" :style="imgStyle"
@click="changeImg(item, index)">
<img :class="index === imgActiveIndex ? 'img_activeBorder' : ''" :src="item" alt="小图" />
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import {
ref, Ref, onBeforeMount, computed } from 'vue'
const props = defineProps({
mainImage: String,
imageList: Array
})
const mainImage = ref(props.mainImage)
const imageList: Ref<any> = ref(props.imageList)
const imgActiveIndex = ref(0)
const imgDistance = ref(0)
const allDistance = ref(0)
const changeImg = (item: string, index: number) => {
mainImage.value = item
imgActiveIndex.value = index
}
const imgLeft = () => {
if (imgActiveIndex.value > 0) {
imgActiveIndex.value--
imageList.value.forEach((item: string, index: number) => {
if (imgActiveIndex.value === index) {
mainImage.value = item
}
})
}
if (imgActiveIndex.value >= 4) {
var index1 = 0
const temp = window.setInterval(() => {
if (index1 < 33) {
imgDistance.value += 2
index1++
return
} else {
window.clearInterval(temp)
}
}, 10)
}
}
const imgRight = () => {
if (imgActiveIndex.value < imageList.value.length - 1) {
imgActiveIndex.value++
imageList.value.forEach((item: string, index: number) => {
if (imgActiveIndex.value === index) {
mainImage.value = item
}
})
if (imgActiveIndex.value >= 5) {
allDistance.value = -66 * (imgActiveIndex.value - 4)
var index2 = 0
const temp = window.setInterval(() => {
if (index2 < 33) {
imgDistance.value -= 2
index2++
return
} else {
window.clearInterval(temp)
}
}, 10)
}
} else if (imgActiveIndex.value === imageList.value.length - 1) {
imgActiveIndex.value = 0
mainImage.value = imageList.value[0]
var index3 = 0
const temp = window.setInterval(() => {
if (index3 < Math.abs(allDistance.value / 2)) {
imgDistance.value += 2
index3++
return
} else {
window.clearInterval(temp)
}
}, 1)
}
}
const imgStyle = computed(() => {
return {
transform: `translate3d(${
imgDistance.value}px, 0, 0)`,
}
})
</script>
<style scoped lang="less">
.goods-imgs {
margin-top: 2px;
width: 100%;
height: 435px;
.imgs-show {
width: 100%;
height: 350px;
img {
width: 100%;
height: 100%;
}
}
.img-thumbnail {
margin-top: 8px;
position: relative;
display: flex;
width: 100%;
height: 85px;
overflow: hidden;
overflow-x: scroll;
list-style: none;
.img-li {
float: left;
margin: 0 8px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
.img_activeBorder {
border: 3px solid #0dcc73;
}
}
}
}
</style>
使用
<!-- 个人主页 -->
<template >
<GoodsImage :mainImage="mainImage" :imageList="imageList"></GoodsImage>
</template>
<script setup lang="ts">
import GoodsImage from '@/components/GoodsImage.vue'
import {
ref} from 'vue'
const mainImage = ref(
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg'
)
const imageList = ref([
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
'https://fuss10.elemecdn.com/2/11/6535bcfb26e4c79b48ddde44f4b6fjpeg.jpeg',
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
'https://fuss10.elemecdn.com/9/bb/e27858e973f5d7d3904835f46abbdjpeg.jpeg',
'https://fuss10.elemecdn.com/d/e6/c4d93a3805b3ce3f323f7974e6f78jpeg.jpeg',
'https://fuss10.elemecdn.com/3/28/bbf893f792f03a54408b3b7a7ebf0jpeg.jpeg',
])
</script>