feat: 调整项目结构
This commit is contained in:
159
src/components/ImageSwiper/index.vue
Normal file
159
src/components/ImageSwiper/index.vue
Normal file
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<view class="image-swiper">
|
||||
<swiper
|
||||
class="swiper-box"
|
||||
:style="swiperStyle"
|
||||
:autoplay="false"
|
||||
:interval="3000"
|
||||
:duration="1000"
|
||||
:current="active"
|
||||
@change="handleSwiperChange"
|
||||
>
|
||||
<swiper-item
|
||||
class="swiper-item"
|
||||
v-for="(item, index) in thumbnails"
|
||||
:key="index"
|
||||
>
|
||||
<image :src="item.photoUrl" mode="aspectFill"></image>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<view class="custom-indicator">
|
||||
图片{{ active + 1 }}/{{ thumbnails.length }}
|
||||
</view>
|
||||
|
||||
<!-- 缩略图部分 -->
|
||||
<view
|
||||
v-if="showThumbnails"
|
||||
class="thumbnail-box"
|
||||
:style="thumbnailBoxStyle"
|
||||
>
|
||||
<scroll-view
|
||||
class="thumbnail-scroll"
|
||||
scroll-x="true"
|
||||
:scroll-left="scrollLeft"
|
||||
:scroll-with-animation="true"
|
||||
show-scrollbar="false"
|
||||
>
|
||||
<view class="thumbnail-list">
|
||||
<view
|
||||
v-for="(thumb, index) in thumbnails"
|
||||
:key="index"
|
||||
:class="['thumbnail-item', { active: index === active }]"
|
||||
:id="`thumbnail-${index}`"
|
||||
@click="handleThumbnailClick(index)"
|
||||
>
|
||||
<image :src="thumb.photoUrl" mode="aspectFill"></image>
|
||||
<text>{{ thumb.photoName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, nextTick } from "vue";
|
||||
|
||||
// Props定义
|
||||
const props = defineProps({
|
||||
// 轮播图圆角大小,支持数字(px)或字符串
|
||||
borderRadius: {
|
||||
type: [Number, String],
|
||||
default: 8,
|
||||
},
|
||||
// 轮播图数据
|
||||
images: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
// 轮播图高度,支持数字(px)或字符串
|
||||
height: {
|
||||
type: [Number, String],
|
||||
default: 200,
|
||||
},
|
||||
// 是否显示缩略图
|
||||
showThumbnails: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
// 缩略图距离底部的距离,支持数字(px)或字符串
|
||||
thumbnailBottom: {
|
||||
type: [Number, String],
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const active = ref(0);
|
||||
const scrollLeft = ref(0);
|
||||
|
||||
// 计算圆角样式
|
||||
const borderRadiusStyle = computed(() => {
|
||||
const radius =
|
||||
typeof props.borderRadius === "number"
|
||||
? `${props.borderRadius}px`
|
||||
: props.borderRadius;
|
||||
return {
|
||||
borderRadius: radius,
|
||||
};
|
||||
});
|
||||
|
||||
// 计算轮播图样式(包含高度和圆角)
|
||||
const swiperStyle = computed(() => {
|
||||
const radius =
|
||||
typeof props.borderRadius === "number"
|
||||
? `${props.borderRadius}px`
|
||||
: props.borderRadius;
|
||||
const swiperHeight =
|
||||
typeof props.height === "number" ? `${props.height}px` : props.height;
|
||||
return {
|
||||
borderRadius: radius,
|
||||
height: swiperHeight,
|
||||
};
|
||||
});
|
||||
|
||||
// 使用传入的图片数据或默认数据
|
||||
const thumbnails = computed(() => props.images);
|
||||
|
||||
// 计算缩略图底部距离样式
|
||||
const thumbnailBoxStyle = computed(() => {
|
||||
const bottom =
|
||||
typeof props.thumbnailBottom === "number"
|
||||
? `${props.thumbnailBottom}px`
|
||||
: props.thumbnailBottom;
|
||||
return {
|
||||
bottom: bottom,
|
||||
};
|
||||
});
|
||||
|
||||
const handleThumbnailClick = (index) => {
|
||||
active.value = index;
|
||||
scrollToActiveItem(index);
|
||||
};
|
||||
|
||||
// 滚动到选中项
|
||||
const scrollToActiveItem = async (index) => {
|
||||
await nextTick();
|
||||
|
||||
// 计算每个缩略图项的宽度(包括间距)
|
||||
const itemWidth = 58; // 48px宽度 + 10px间距
|
||||
const containerWidth = 300; // 大概的容器宽度
|
||||
const targetScrollLeft = Math.max(
|
||||
0,
|
||||
index * itemWidth - containerWidth / 2 + itemWidth / 2
|
||||
);
|
||||
|
||||
scrollLeft.value = targetScrollLeft;
|
||||
};
|
||||
|
||||
// 监听主轮播图变化,同步缩略图滚动
|
||||
const handleSwiperChange = (e) => {
|
||||
const currentIndex = e.detail.current;
|
||||
active.value = currentIndex;
|
||||
scrollToActiveItem(currentIndex);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@use "./styles/index.scss";
|
||||
</style>
|
||||
Reference in New Issue
Block a user