7 changed files with 405 additions and 20 deletions
@ -0,0 +1,384 @@ |
|||
<template> |
|||
<view class="product-section"> |
|||
<view class="title-section"> |
|||
<div |
|||
style=" |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
" |
|||
@click="handleMoreClick" |
|||
> |
|||
<text class="title">文化IP合作体</text> |
|||
</div> |
|||
</view> |
|||
<!-- 轮播容器 --> |
|||
<view class="carousel-container"> |
|||
<!-- 左箭头 --> |
|||
<view |
|||
class="nav-arrow left-arrow" |
|||
@click="prevSlide" |
|||
v-if="list.length > 1 && currentIndex > 0" |
|||
> |
|||
<image style="width: 50rpx;height: 50rpx;" :src="showImg('/uploads/20250908/29beeddf1e45571d2c5a4187f2f1ae05.png')"></image> |
|||
</view> |
|||
|
|||
<!-- 轮播内容 --> |
|||
<scroll-view |
|||
class="carousel-scroll" |
|||
scroll-x="true" |
|||
:show-scrollbar="false" |
|||
:enhanced="true" |
|||
:scroll-with-animation="true" |
|||
:scroll-left="scrollLeft" |
|||
@scroll="onScroll" |
|||
@scrollend="onScrollEnd" |
|||
> |
|||
<view class="carousel-content"> |
|||
<view |
|||
class="carousel-item" |
|||
v-for="(item, index) in list" |
|||
:key="index" |
|||
@click="gotoUrlNew(item)" |
|||
v-if="item && item.image" |
|||
> |
|||
<view class="issue-card"> |
|||
<!-- 背景图片 --> |
|||
<image |
|||
class="card-bg" |
|||
:src="showImg(item.image)" |
|||
mode="aspectFill" |
|||
></image> |
|||
<view class="title-info"> |
|||
<view class="title-item"> |
|||
{{item.title}} |
|||
</view> |
|||
<view class="title-des"> |
|||
{{item.des}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<!-- 无数据时的提示 --> |
|||
<view v-if="!list || list.length === 0" class="no-data"> |
|||
<text>暂无数据</text> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
|
|||
<!-- 右箭头 --> |
|||
<view |
|||
class="nav-arrow right-arrow" |
|||
@click="nextSlide" |
|||
v-if="list.length > 1 && currentIndex < list.length - 1" |
|||
> |
|||
|
|||
<image style="width: 50rpx;height: 50rpx;" :src="showImg('/uploads/20250908/6622b3699518d6b559e1241d7addb7af.png')"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
image:'/uploads/20250908/bb069c36e88de7cde4e8dd24ac3b33b5.png', |
|||
title:'太湖', |
|||
des:'NAINO的异次元发现', |
|||
}, |
|||
{ |
|||
image:'/uploads/20250908/ab1ffc93875de79fc87ee2c5e70cad3f.png', |
|||
title:'SUNRISE日出东方', |
|||
des:'扬州瓜洲古渡', |
|||
}, |
|||
{ |
|||
image:'/uploads/20250908/4d38fcd2e403a13b85a96188de12a2a8.png', |
|||
title:'中国昆曲博物馆', |
|||
des:'姹紫婿红里', |
|||
}, |
|||
{ |
|||
image:'/uploads/20250908/d4115d6c907f8b3ed5d30a11f9912460.png', |
|||
title:'退思园', |
|||
des:'苏州古典园林生活', |
|||
}], |
|||
currentIndex: 0, |
|||
scrollLeft: 0, |
|||
itemWidth: 224, // 207rpx + 30rpx margin |
|||
JDSU_IMG_URL: "https://epic.js-dyyj.com", |
|||
}; |
|||
}, |
|||
mounted() { |
|||
// this.getList(); |
|||
}, |
|||
methods: { |
|||
handleMoreClick(){ |
|||
uni.switchTab({ |
|||
url:'/pages/index/readingBody' |
|||
}) |
|||
}, |
|||
getList() { |
|||
// this.Post( |
|||
// { |
|||
// type_id: 3, |
|||
// offset: 0, |
|||
// limit: 10, // 增加获取数量,确保有足够数据 |
|||
// }, |
|||
// "/api/article/getArticleByType" |
|||
// ).then((res) => { |
|||
// if (res.data && res.data.length > 0) { |
|||
// this.list = res.data; |
|||
// // 重置索引,确保从第一项开始 |
|||
// this.currentIndex = 0; |
|||
// this.scrollLeft = 0; |
|||
// } |
|||
// }); |
|||
}, |
|||
|
|||
// 图片显示方法 |
|||
showImg(img) { |
|||
if (!img) return ""; |
|||
if (img.indexOf("https://") != -1 || img.indexOf("http://") != -1) { |
|||
return img; |
|||
} else { |
|||
return this.JDSU_IMG_URL + img; |
|||
} |
|||
}, |
|||
|
|||
// 上一张 |
|||
prevSlide() { |
|||
if (!this.validateData()) return; |
|||
|
|||
if (this.list.length > 1) { |
|||
this.currentIndex = |
|||
this.currentIndex > 0 ? this.currentIndex - 1 : this.list.length - 1; |
|||
this.$nextTick(() => { |
|||
this.scrollToCurrentItem(); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 下一张 |
|||
nextSlide() { |
|||
if (!this.validateData()) return; |
|||
|
|||
if (this.list.length > 1) { |
|||
this.currentIndex = |
|||
this.currentIndex < this.list.length - 1 ? this.currentIndex + 1 : 0; |
|||
this.$nextTick(() => { |
|||
this.scrollToCurrentItem(); |
|||
}); |
|||
} |
|||
}, |
|||
|
|||
// 滚动到当前项目 |
|||
scrollToCurrentItem() { |
|||
// 确保索引在有效范围内 |
|||
if (this.currentIndex < 0) { |
|||
this.currentIndex = 0; |
|||
} |
|||
if (this.currentIndex >= this.list.length) { |
|||
this.currentIndex = this.list.length - 1; |
|||
} |
|||
|
|||
const scrollPosition = this.currentIndex * this.itemWidth; |
|||
this.scrollLeft = scrollPosition; |
|||
}, |
|||
|
|||
// 滚动事件 |
|||
onScroll(e) { |
|||
const scrollLeft = e.detail.scrollLeft; |
|||
const index = Math.round(scrollLeft / this.itemWidth); |
|||
if ( |
|||
index !== this.currentIndex && |
|||
index >= 0 && |
|||
index < this.list.length |
|||
) { |
|||
this.currentIndex = index; |
|||
} |
|||
}, |
|||
|
|||
// 滚动结束事件 |
|||
onScrollEnd(e) { |
|||
const scrollLeft = e.detail.scrollLeft; |
|||
const index = Math.round(scrollLeft / this.itemWidth); |
|||
// 确保索引在有效范围内 |
|||
this.currentIndex = Math.max(0, Math.min(index, this.list.length - 1)); |
|||
this.$nextTick(() => { |
|||
this.scrollToCurrentItem(); |
|||
}); |
|||
}, |
|||
|
|||
// 点击卡片 |
|||
handleItemClick(item) { |
|||
console.log("点击了卡片:", item); |
|||
// 这里可以添加跳转逻辑 |
|||
}, |
|||
|
|||
// 验证数据有效性 |
|||
validateData() { |
|||
if (!this.list || this.list.length === 0) { |
|||
this.currentIndex = 0; |
|||
this.scrollLeft = 0; |
|||
return false; |
|||
} |
|||
|
|||
// 确保当前索引在有效范围内 |
|||
if (this.currentIndex < 0) { |
|||
this.currentIndex = 0; |
|||
} |
|||
if (this.currentIndex >= this.list.length) { |
|||
this.currentIndex = this.list.length - 1; |
|||
} |
|||
|
|||
return true; |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.product-section { |
|||
width: 100%; |
|||
background-color: #fffdd6; |
|||
padding: 40rpx 25rpx; |
|||
margin: 30rpx 0; |
|||
border-radius: 40rpx; |
|||
box-shadow: 0 8rpx 32rpx rgba(0, 0, 0, 0.1), |
|||
0 0 0 1rpx rgba(255, 255, 255, 0.2) inset; |
|||
} |
|||
|
|||
// 轮播容器 |
|||
.carousel-container { |
|||
position: relative; |
|||
width: 100%; |
|||
height: 191rpx ; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
|
|||
// 轮播滚动视图 |
|||
.carousel-scroll { |
|||
width: 100%; |
|||
height: 100%; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
// 轮播内容 |
|||
.carousel-content { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 100%; |
|||
min-width: max-content; |
|||
} |
|||
|
|||
// 轮播项 |
|||
.carousel-item { |
|||
flex-shrink: 0; |
|||
width: 154rpx; |
|||
height: 191rpx; |
|||
margin: 0 7rpx; |
|||
will-change: transform; |
|||
} |
|||
|
|||
// 卡片样式 |
|||
.issue-card { |
|||
width: 100%; |
|||
height: 100%; |
|||
position: relative; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
// 背景图片 |
|||
.card-bg { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
|
|||
// 导航箭头 |
|||
.nav-arrow { |
|||
position: absolute; |
|||
top: 50%; |
|||
transform: translateY(-50%); |
|||
width: 60rpx; |
|||
height: 60rpx; |
|||
border-radius: 50%; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
cursor: pointer; |
|||
z-index: 3; |
|||
transition: all 0.3s ease; |
|||
|
|||
&.left-arrow { |
|||
left: 0rpx; |
|||
} |
|||
|
|||
&.right-arrow { |
|||
right: 0rpx; |
|||
} |
|||
} |
|||
|
|||
.arrow-icon { |
|||
font-size: 32rpx; |
|||
color: #ffffff; |
|||
font-weight: bold; |
|||
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3); |
|||
} |
|||
|
|||
// 无数据提示 |
|||
.no-data { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
width: 100%; |
|||
height: 368rpx; |
|||
color: #999; |
|||
font-size: 28rpx; |
|||
} |
|||
|
|||
// 标题区域 |
|||
.title-section { |
|||
display: inline-block; |
|||
padding: 0rpx 0 30rpx; |
|||
width: 100%; |
|||
.title { |
|||
font-size: 34rpx; |
|||
font-weight: bold; |
|||
color: #000000; |
|||
} |
|||
|
|||
.more-btn { |
|||
font-size: 26rpx; |
|||
color: #000000; |
|||
margin-left: 35rpx; |
|||
} |
|||
} |
|||
.title-info{ |
|||
position: absolute; |
|||
bottom: 10rpx; |
|||
right: 0; |
|||
width: 100%; |
|||
color: white; |
|||
padding: 0 5rpx; |
|||
.title-item{ |
|||
text-align: center; |
|||
font-size: 16rpx; |
|||
font-weight: bold; |
|||
overflow: hidden; |
|||
word-wrap: normal; |
|||
text-overflow: ellipsis; |
|||
} |
|||
.title-des{ |
|||
margin-top: 5rpx; |
|||
text-align: center; |
|||
font-size: 14rpx; |
|||
overflow: hidden; |
|||
word-wrap: normal; |
|||
text-overflow: ellipsis; |
|||
} |
|||
} |
|||
</style> |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.6 KiB |
Loading…
Reference in new issue