Files
nanocode/wanandroid/uniapp/components/home/banner.vue
T
Ubuntu 32b43f85bd a
2026-07-03 16:58:28 +08:00

205 lines
4.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="banner-container">
<swiper
class="banner-swiper"
:indicator-dots="indicatorDots"
:autoplay="autoplay"
:interval="interval"
:duration="duration"
:circular="circular"
@change="onSwiperChange"
>
<swiper-item
v-for="(item, index) in bannerList"
:key="item.id || index"
class="banner-item"
>
<view class="banner-content" @click="handleBannerClick(item)">
<image
class="banner-image"
:src="item.imagePath || item.image || item.pic"
mode="aspectFill"
lazy-load
/>
<view class="banner-mask" v-if="showTitle">
<text class="banner-title">{{ item.title }}</text>
</view>
</view>
</swiper-item>
</swiper>
<!-- 指示器(自定义样式) -->
<view class="custom-indicator" v-if="showCustomIndicator">
<view
class="indicator-dot"
v-for="(item, index) in bannerList"
:key="index"
:class="{ active: currentIndex === index }"
></view>
</view>
</view>
</template>
<script>
export default {
name: 'HomeBanner',
props: {
// Banner数据列表
bannerList: {
type: Array,
default: () => []
},
// 是否显示指示点
indicatorDots: {
type: Boolean,
default: true
},
// 是否自动播放
autoplay: {
type: Boolean,
default: true
},
// 自动切换时间间隔(ms)
interval: {
type: Number,
default: 3000
},
// 滑动动画时长(ms)
duration: {
type: Number,
default: 500
},
// 是否采用衔接滑动
circular: {
type: Boolean,
default: true
},
// 是否显示标题
showTitle: {
type: Boolean,
default: true
},
// 是否显示自定义指示器
showCustomIndicator: {
type: Boolean,
default: false
}
},
data() {
return {
currentIndex: 0
}
},
methods: {
onSwiperChange(e) {
this.currentIndex = e.detail.current
this.$emit('change', {
index: this.currentIndex,
item: this.bannerList[this.currentIndex]
})
},
handleBannerClick(item) {
this.$emit('click', item)
// 处理Banner点击跳转
if (item.url) {
// 如果是外部链接
if (item.url.startsWith('http')) {
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(item.url)}`
})
}
} else if (item.link) {
// 处理内部链接
this.handleInternalLink(item.link)
}
},
handleInternalLink(link) {
// 这里可以根据link格式处理不同的跳转逻辑
console.log('Banner内部链接:', link)
// 可以扩展处理不同的链接类型
}
}
}
</script>
<style scoped>
.banner-container {
position: relative;
width: 100%;
height: 350rpx;
}
.banner-swiper {
width: 100%;
height: 100%;
}
.banner-item {
width: 100%;
height: 100%;
}
.banner-content {
width: 100%;
height: 100%;
position: relative;
border-radius: 16rpx;
overflow: hidden;
}
.banner-image {
width: 100%;
height: 100%;
}
.banner-mask {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx 40rpx;
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
}
.banner-title {
font-size: 32rpx;
font-weight: 500;
color: #fff;
line-height: 1.4;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
/* 自定义指示器 */
.custom-indicator {
position: absolute;
bottom: 30rpx;
left: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 10;
}
.indicator-dot {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
margin: 0 8rpx;
transition: all 0.3s ease;
}
.indicator-dot.active {
width: 32rpx;
border-radius: 8rpx;
background-color: #fff;
}
</style>