- 发布:2026-10-26 10:55
- 更新:2026-10-26 10:57
- 阅读:53
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: 64位
HBuilderX类型: 正式
HBuilderX版本号: 5.24
手机系统: 全部
手机厂商: 华为
页面类型: vue
vue版本: vue3
打包方式: 云端
项目创建方式: HBuilderX
测试过的手机:
示例代码:
<template>
<view class="banner_con">
<swiper
class="banner"
circular
autoplay="true"
interval="4000"
duration="450"
current="bannerCur"
@change="bannerChange"
<swiper-item v-for="(b, i) in banners" :key="i">
<view class="banner_slide" :class="b.cls">
<view class="bs_deco1"></view>
<view class="bs_deco2"></view>
<view class="bs_text">
<text class="bs_tag">{{ b.tag }}</text>
<text class="bs_title">{{ b.title }}</text>
<text class="bs_sub">{{ b.sub }}</text>
</view>
<!-- <view class="bs_btn">
<text>{{ b.btn }}</text>
<view class="bs_arrow"></view>
</view> -->
</view>
</swiper-item>
</swiper>
<!-- 关闭叉号 -->
<view class="banner_close" @tap.stop="closeBanner">
<view class="close_x"></view>
</view>
<!-- 指示点 -->
<view class="banner_dots">
<view
v-for="(b, i) in banners"
key="i"
class="dot"
class="{ on: bannerCur === i }"
@tap.stop="goBanner(i)"
></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const app = getApp()
const emit = defineEmits(["clsoeBanner"])
const bannerCur = ref(0)// 当前轮播索引
/* ================= 轮播数据(通用智能设备主题) ================= */
const banners = [
{ cls: 'bs_1', tag: 'SMART', title: app.$vm.$i18n.t('banner.oneTitle'), sub: app.$vm.$i18n.t('banner.oneSubTitle'), btn: '了解更多', link: '了解更多' },
{ cls: 'bs_2', tag: 'GUARD', title: app.$vm.$i18n.t('banner.twoTitle'), sub: app.$vm.$i18n.t('banner.twoSubTitle'), btn: '开启提醒', link: '消息提醒' },
{ cls: 'bs_3', tag: 'SHARE', title: app.$vm.$i18n.t('banner.threeTitle'), sub: app.$vm.$i18n.t('banner.threeSubTitle'), btn: '立即邀请', link: '共享设备' }
]
/* ================= 轮播 ================= */
const bannerChange = e => {
const cur = e.detail.current
if (cur !== bannerCur.value){
bannerCur.value = cur
}
}
const goBanner = i => {
if (i === bannerCur.value) return
bannerCur.value = i
}
const closeBanner = () => {
// showBanner.value = false
emit("clsoeBanner")
}
</script>
<style lang="scss" scoped>
/ ===== 轮播图 ===== /
.banner_con {
position: relative;
// z-index: 1;
margin-top: 28rpx;
// box-shadow: 0 24rpx 56rpx rgba(46, 123, 255, .22);
}
.banner {
height: 192rpx;
border-radius: 36rpx;
overflow: hidden;
}
.banner_slide {
position: relative;
height: 192rpx;
padding: 0 36rpx;
overflow: hidden;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.bs_1 {
background-image: linear-gradient(118deg, #4E9AFF 0%, #2E7BFF 52%, #5F6BFF 100%);
}
.bs_2 {
background-image: linear-gradient(118deg, #38B9D8 0%, #2E9BFF 55%, #2E7BFF 100%);
}
.bs_3 {
background-image: linear-gradient(118deg, #7B6BFF 0%, #3E7BFF 58%, #4E9AFF 100%);
}
/* 光晕装饰 */
.bs_deco1 {
position: absolute;
width: 300rpx;
height: 300rpx;
right: -80rpx;
top: -140rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .20), transparent);
}
.bs_deco2 {
position: absolute;
width: 220rpx;
height: 220rpx;
left: -100rpx;
bottom: -120rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .12), transparent);
}
.bs_text {
position: relative;
z-index: 2;
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.bs_tag {
font-size: 19rpx;
font-weight: 700;
letter-spacing: 2rpx;
background: rgba(255, 255, 255, .22);
border-radius: 999rpx;
padding: 4rpx 16rpx;
margin-bottom: 10rpx;
}
.bs_title {
font-size: 35rpx;
font-weight: 800;
line-height: 1.3;
}
.bs_sub {
margin-top: 6rpx;
font-size: 23rpx;
opacity: .85;
}
// .bs_btn {
// position: relative;
// z-index: 2;
// flex: none;
// display: flex;
// flex-direction: row;
// align-items: center;
// background: #fff;
// color: #2E7BFF;
// border-radius: 999rpx;
// padding: 12rpx 26rpx;
// font-size: 24rpx;
// font-weight: 800;
// box-shadow: 0 10rpx 24rpx rgba(15, 50, 120, .22);
// }
// .bs_arrow {
// width: 14rpx;
// height: 14rpx;
// border-top: 3rpx solid #2E7BFF;
// border-right: 3rpx solid #2E7BFF;
// transform: rotate(45deg);
// margin-left: 8rpx;
// }
/* 关闭叉号 */
.banner_close {
position: absolute;
right: 16rpx;
top: 16rpx;
// z-index: 5;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(23, 50, 110, .22);
display: flex;
align-items: center;
justify-content: center;
}
.close_x {
position: relative;
width: 22rpx;
height: 22rpx;
}
.close_x::before,
.close_x::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 22rpx;
height: 3rpx;
border-radius: 2rpx;
background: #fff;
}
.close_x::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.close_x::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
/* 指示点 */
.banner_dots {
position: absolute;
right: 28rpx;
bottom: 18rpx;
// z-index: 4;
display: flex;
flex-direction: row;
}
.dot {
width: 10rpx;
height: 10rpx;
border-radius: 99rpx;
background: rgba(255, 255, 255, .45);
margin-left: 10rpx;
transition: all .3s;
}
.dot.on {
width: 28rpx;
background: #fff;
}
</style>
current="bannerCur" @change="bannerChange"
<swiper-item v-for="(b, i) in banners" :key="i">
<view class="banner_slide" :class="b.cls">
<view class="bs_deco1"></view>
<view class="bs_deco2"></view>
<view class="bs_text">
<text class="bs_tag">{{ b.tag }}</text>
<text class="bs_title">{{ b.title }}</text>
<text class="bs_sub">{{ b.sub }}</text>
</view>
<!-- <view class="bs_btn">
<text>{{ b.btn }}</text>
<view class="bs_arrow"></view>
</view> -->
</view>
</swiper-item>
</swiper>
<!-- 关闭叉号 -->
<view class="banner_close" @tap.stop="closeBanner">
<view class="close_x"></view>
</view>
<!-- 指示点 -->
<view class="banner_dots">
<view
v-for="(b, i) in banners"
key="i"
class="dot"
class="{ on: bannerCur === i }"
@tap.stop="goBanner(i)"></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const app = getApp()
const emit = defineEmits(["clsoeBanner"])
const bannerCur = ref(0)// 当前轮播索引
/* ================= 轮播数据(通用智能设备主题) ================= */
const banners = [
{ cls: 'bs_1', tag: 'SMART', title: app.$vm.$i18n.t('banner.oneTitle'), sub: app.$vm.$i18n.t('banner.oneSubTitle'), btn: '了解更多', link: '了解更多' },
{ cls: 'bs_2', tag: 'GUARD', title: app.$vm.$i18n.t('banner.twoTitle'), sub: app.$vm.$i18n.t('banner.twoSubTitle'), btn: '开启提醒', link: '消息提醒' },
{ cls: 'bs_3', tag: 'SHARE', title: app.$vm.$i18n.t('banner.threeTitle'), sub: app.$vm.$i18n.t('banner.threeSubTitle'), btn: '立即邀请', link: '共享设备' }
]
/* ================= 轮播 ================= */
const bannerChange = e => {
const cur = e.detail.current
if (cur !== bannerCur.value){
bannerCur.value = cur
}
}
const goBanner = i => {
if (i === bannerCur.value) return
bannerCur.value = i
}
const closeBanner = () => {
// showBanner.value = false
emit("clsoeBanner")
}
</script>
<style lang="scss" scoped>
/ ===== 轮播图 ===== /
.banner_con {
position: relative;
// z-index: 1;
margin-top: 28rpx;
// box-shadow: 0 24rpx 56rpx rgba(46, 123, 255, .22);
}
.banner {
height: 192rpx;
border-radius: 36rpx;
overflow: hidden;
}
.banner_slide {
position: relative;
height: 192rpx;
padding: 0 36rpx;
overflow: hidden;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.bs_1 {
background-image: linear-gradient(118deg, #4E9AFF 0%, #2E7BFF 52%, #5F6BFF 100%);
}
.bs_2 {
background-image: linear-gradient(118deg, #38B9D8 0%, #2E9BFF 55%, #2E7BFF 100%);
}
.bs_3 {
background-image: linear-gradient(118deg, #7B6BFF 0%, #3E7BFF 58%, #4E9AFF 100%);
}
/* 光晕装饰 */
.bs_deco1 {
position: absolute;
width: 300rpx;
height: 300rpx;
right: -80rpx;
top: -140rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .20), transparent);
}
.bs_deco2 {
position: absolute;
width: 220rpx;
height: 220rpx;
left: -100rpx;
bottom: -120rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .12), transparent);
}
.bs_text {
position: relative;
z-index: 2;
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.bs_tag {
font-size: 19rpx;
font-weight: 700;
letter-spacing: 2rpx;
background: rgba(255, 255, 255, .22);
border-radius: 999rpx;
padding: 4rpx 16rpx;
margin-bottom: 10rpx;
}
.bs_title {
font-size: 35rpx;
font-weight: 800;
line-height: 1.3;
}
.bs_sub {
margin-top: 6rpx;
font-size: 23rpx;
opacity: .85;
}
// .bs_btn {
// position: relative;
// z-index: 2;
// flex: none;
// display: flex;
// flex-direction: row;
// align-items: center;
// background: #fff;
// color: #2E7BFF;
// border-radius: 999rpx;
// padding: 12rpx 26rpx;
// font-size: 24rpx;
// font-weight: 800;
// box-shadow: 0 10rpx 24rpx rgba(15, 50, 120, .22);
// }
// .bs_arrow {
// width: 14rpx;
// height: 14rpx;
// border-top: 3rpx solid #2E7BFF;
// border-right: 3rpx solid #2E7BFF;
// transform: rotate(45deg);
// margin-left: 8rpx;
// }
/* 关闭叉号 */
.banner_close {
position: absolute;
right: 16rpx;
top: 16rpx;
// z-index: 5;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(23, 50, 110, .22);
display: flex;
align-items: center;
justify-content: center;
}
.close_x {
position: relative;
width: 22rpx;
height: 22rpx;
}
.close_x::before,
.close_x::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 22rpx;
height: 3rpx;
border-radius: 2rpx;
background: #fff;
}
.close_x::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.close_x::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
/* 指示点 */
.banner_dots {
position: absolute;
right: 28rpx;
bottom: 18rpx;
// z-index: 4;
display: flex;
flex-direction: row;
}
.dot {
width: 10rpx;
height: 10rpx;
border-radius: 99rpx;
background: rgba(255, 255, 255, .45);
margin-left: 10rpx;
transition: all .3s;
}
.dot.on {
width: 28rpx;
background: #fff;
}
</style>
操作步骤:
<template>
<view class="banner_con">
<swiper
class="banner"
circular
autoplay="true"
interval="4000"
duration="450"
current="bannerCur"
@change="bannerChange"
<swiper-item v-for="(b, i) in banners" :key="i">
<view class="banner_slide" :class="b.cls">
<view class="bs_deco1"></view>
<view class="bs_deco2"></view>
<view class="bs_text">
<text class="bs_tag">{{ b.tag }}</text>
<text class="bs_title">{{ b.title }}</text>
<text class="bs_sub">{{ b.sub }}</text>
</view>
<!-- <view class="bs_btn">
<text>{{ b.btn }}</text>
<view class="bs_arrow"></view>
</view> -->
</view>
</swiper-item>
</swiper>
<!-- 关闭叉号 -->
<view class="banner_close" @tap.stop="closeBanner">
<view class="close_x"></view>
</view>
<!-- 指示点 -->
<view class="banner_dots">
<view
v-for="(b, i) in banners"
key="i"
class="dot"
class="{ on: bannerCur === i }"
@tap.stop="goBanner(i)"
></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const app = getApp()
const emit = defineEmits(["clsoeBanner"])
const bannerCur = ref(0)// 当前轮播索引
/* ================= 轮播数据(通用智能设备主题) ================= */
const banners = [
{ cls: 'bs_1', tag: 'SMART', title: app.$vm.$i18n.t('banner.oneTitle'), sub: app.$vm.$i18n.t('banner.oneSubTitle'), btn: '了解更多', link: '了解更多' },
{ cls: 'bs_2', tag: 'GUARD', title: app.$vm.$i18n.t('banner.twoTitle'), sub: app.$vm.$i18n.t('banner.twoSubTitle'), btn: '开启提醒', link: '消息提醒' },
{ cls: 'bs_3', tag: 'SHARE', title: app.$vm.$i18n.t('banner.threeTitle'), sub: app.$vm.$i18n.t('banner.threeSubTitle'), btn: '立即邀请', link: '共享设备' }
]
/* ================= 轮播 ================= */
const bannerChange = e => {
const cur = e.detail.current
if (cur !== bannerCur.value){
bannerCur.value = cur
}
}
const goBanner = i => {
if (i === bannerCur.value) return
bannerCur.value = i
}
const closeBanner = () => {
// showBanner.value = false
emit("clsoeBanner")
}
</script>
<style lang="scss" scoped>
/ ===== 轮播图 ===== /
.banner_con {
position: relative;
// z-index: 1;
margin-top: 28rpx;
// box-shadow: 0 24rpx 56rpx rgba(46, 123, 255, .22);
}
.banner {
height: 192rpx;
border-radius: 36rpx;
overflow: hidden;
}
.banner_slide {
position: relative;
height: 192rpx;
padding: 0 36rpx;
overflow: hidden;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.bs_1 {
background-image: linear-gradient(118deg, #4E9AFF 0%, #2E7BFF 52%, #5F6BFF 100%);
}
.bs_2 {
background-image: linear-gradient(118deg, #38B9D8 0%, #2E9BFF 55%, #2E7BFF 100%);
}
.bs_3 {
background-image: linear-gradient(118deg, #7B6BFF 0%, #3E7BFF 58%, #4E9AFF 100%);
}
/* 光晕装饰 */
.bs_deco1 {
position: absolute;
width: 300rpx;
height: 300rpx;
right: -80rpx;
top: -140rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .20), transparent);
}
.bs_deco2 {
position: absolute;
width: 220rpx;
height: 220rpx;
left: -100rpx;
bottom: -120rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .12), transparent);
}
.bs_text {
position: relative;
z-index: 2;
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.bs_tag {
font-size: 19rpx;
font-weight: 700;
letter-spacing: 2rpx;
background: rgba(255, 255, 255, .22);
border-radius: 999rpx;
padding: 4rpx 16rpx;
margin-bottom: 10rpx;
}
.bs_title {
font-size: 35rpx;
font-weight: 800;
line-height: 1.3;
}
.bs_sub {
margin-top: 6rpx;
font-size: 23rpx;
opacity: .85;
}
// .bs_btn {
// position: relative;
// z-index: 2;
// flex: none;
// display: flex;
// flex-direction: row;
// align-items: center;
// background: #fff;
// color: #2E7BFF;
// border-radius: 999rpx;
// padding: 12rpx 26rpx;
// font-size: 24rpx;
// font-weight: 800;
// box-shadow: 0 10rpx 24rpx rgba(15, 50, 120, .22);
// }
// .bs_arrow {
// width: 14rpx;
// height: 14rpx;
// border-top: 3rpx solid #2E7BFF;
// border-right: 3rpx solid #2E7BFF;
// transform: rotate(45deg);
// margin-left: 8rpx;
// }
/* 关闭叉号 */
.banner_close {
position: absolute;
right: 16rpx;
top: 16rpx;
// z-index: 5;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(23, 50, 110, .22);
display: flex;
align-items: center;
justify-content: center;
}
.close_x {
position: relative;
width: 22rpx;
height: 22rpx;
}
.close_x::before,
.close_x::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 22rpx;
height: 3rpx;
border-radius: 2rpx;
background: #fff;
}
.close_x::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.close_x::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
/* 指示点 */
.banner_dots {
position: absolute;
right: 28rpx;
bottom: 18rpx;
// z-index: 4;
display: flex;
flex-direction: row;
}
.dot {
width: 10rpx;
height: 10rpx;
border-radius: 99rpx;
background: rgba(255, 255, 255, .45);
margin-left: 10rpx;
transition: all .3s;
}
.dot.on {
width: 28rpx;
background: #fff;
}
</style>
current="bannerCur" @change="bannerChange"
<swiper-item v-for="(b, i) in banners" :key="i">
<view class="banner_slide" :class="b.cls">
<view class="bs_deco1"></view>
<view class="bs_deco2"></view>
<view class="bs_text">
<text class="bs_tag">{{ b.tag }}</text>
<text class="bs_title">{{ b.title }}</text>
<text class="bs_sub">{{ b.sub }}</text>
</view>
<!-- <view class="bs_btn">
<text>{{ b.btn }}</text>
<view class="bs_arrow"></view>
</view> -->
</view>
</swiper-item>
</swiper>
<!-- 关闭叉号 -->
<view class="banner_close" @tap.stop="closeBanner">
<view class="close_x"></view>
</view>
<!-- 指示点 -->
<view class="banner_dots">
<view
v-for="(b, i) in banners"
key="i"
class="dot"
class="{ on: bannerCur === i }"
@tap.stop="goBanner(i)"></view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const app = getApp()
const emit = defineEmits(["clsoeBanner"])
const bannerCur = ref(0)// 当前轮播索引
/* ================= 轮播数据(通用智能设备主题) ================= */
const banners = [
{ cls: 'bs_1', tag: 'SMART', title: app.$vm.$i18n.t('banner.oneTitle'), sub: app.$vm.$i18n.t('banner.oneSubTitle'), btn: '了解更多', link: '了解更多' },
{ cls: 'bs_2', tag: 'GUARD', title: app.$vm.$i18n.t('banner.twoTitle'), sub: app.$vm.$i18n.t('banner.twoSubTitle'), btn: '开启提醒', link: '消息提醒' },
{ cls: 'bs_3', tag: 'SHARE', title: app.$vm.$i18n.t('banner.threeTitle'), sub: app.$vm.$i18n.t('banner.threeSubTitle'), btn: '立即邀请', link: '共享设备' }
]
/* ================= 轮播 ================= */
const bannerChange = e => {
const cur = e.detail.current
if (cur !== bannerCur.value){
bannerCur.value = cur
}
}
const goBanner = i => {
if (i === bannerCur.value) return
bannerCur.value = i
}
const closeBanner = () => {
// showBanner.value = false
emit("clsoeBanner")
}
</script>
<style lang="scss" scoped>
/ ===== 轮播图 ===== /
.banner_con {
position: relative;
// z-index: 1;
margin-top: 28rpx;
// box-shadow: 0 24rpx 56rpx rgba(46, 123, 255, .22);
}
.banner {
height: 192rpx;
border-radius: 36rpx;
overflow: hidden;
}
.banner_slide {
position: relative;
height: 192rpx;
padding: 0 36rpx;
overflow: hidden;
color: #fff;
display: flex;
flex-direction: row;
align-items: center;
}
.bs_1 {
background-image: linear-gradient(118deg, #4E9AFF 0%, #2E7BFF 52%, #5F6BFF 100%);
}
.bs_2 {
background-image: linear-gradient(118deg, #38B9D8 0%, #2E9BFF 55%, #2E7BFF 100%);
}
.bs_3 {
background-image: linear-gradient(118deg, #7B6BFF 0%, #3E7BFF 58%, #4E9AFF 100%);
}
/* 光晕装饰 */
.bs_deco1 {
position: absolute;
width: 300rpx;
height: 300rpx;
right: -80rpx;
top: -140rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .20), transparent);
}
.bs_deco2 {
position: absolute;
width: 220rpx;
height: 220rpx;
left: -100rpx;
bottom: -120rpx;
border-radius: 50%;
background: radial-gradient(closest-side, rgba(255, 255, 255, .12), transparent);
}
.bs_text {
position: relative;
z-index: 2;
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.bs_tag {
font-size: 19rpx;
font-weight: 700;
letter-spacing: 2rpx;
background: rgba(255, 255, 255, .22);
border-radius: 999rpx;
padding: 4rpx 16rpx;
margin-bottom: 10rpx;
}
.bs_title {
font-size: 35rpx;
font-weight: 800;
line-height: 1.3;
}
.bs_sub {
margin-top: 6rpx;
font-size: 23rpx;
opacity: .85;
}
// .bs_btn {
// position: relative;
// z-index: 2;
// flex: none;
// display: flex;
// flex-direction: row;
// align-items: center;
// background: #fff;
// color: #2E7BFF;
// border-radius: 999rpx;
// padding: 12rpx 26rpx;
// font-size: 24rpx;
// font-weight: 800;
// box-shadow: 0 10rpx 24rpx rgba(15, 50, 120, .22);
// }
// .bs_arrow {
// width: 14rpx;
// height: 14rpx;
// border-top: 3rpx solid #2E7BFF;
// border-right: 3rpx solid #2E7BFF;
// transform: rotate(45deg);
// margin-left: 8rpx;
// }
/* 关闭叉号 */
.banner_close {
position: absolute;
right: 16rpx;
top: 16rpx;
// z-index: 5;
width: 48rpx;
height: 48rpx;
border-radius: 50%;
background: rgba(23, 50, 110, .22);
display: flex;
align-items: center;
justify-content: center;
}
.close_x {
position: relative;
width: 22rpx;
height: 22rpx;
}
.close_x::before,
.close_x::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 22rpx;
height: 3rpx;
border-radius: 2rpx;
background: #fff;
}
.close_x::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.close_x::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
/* 指示点 */
.banner_dots {
position: absolute;
right: 28rpx;
bottom: 18rpx;
// z-index: 4;
display: flex;
flex-direction: row;
}
.dot {
width: 10rpx;
height: 10rpx;
border-radius: 99rpx;
background: rgba(255, 255, 255, .45);
margin-left: 10rpx;
transition: all .3s;
}
.dot.on {
width: 28rpx;
background: #fff;
}
</style>
预期结果:
预期跟正常的轮播图一样
预期跟正常的轮播图一样
实际结果:
实际的效果一卡一卡的
实际的效果一卡一卡的
bug描述:
偶尔会发生 组件一卡一卡的
Ask小助手 - Ask社区AI助手
欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。
感谢提交这条 bug 反馈。以下以官方评审视角对该反馈进行评审:
一、反馈完整性评审
目前反馈已包含标题、问题描述、代码示例和部分分类信息(Windows 64位、HBuilderX 正式版 5.24、Vue3、手机OS平台“全部”、厂商华为),但存在以下不足,需要补充:
-
BUG 描述过于简略。“偶尔会发生 组件一卡一卡的”“卡住一样一闪一闪”表述模糊,官方人员难以据此定位。建议补充:
- “一闪一闪”的具体表现:是切换动画执行到一半被中断回弹?是 swiper-item 画面白屏/跳变?还是自定义指示点先跳再回?
- 触发时机:出现在自动轮播(autoplay)切换时、手指滑动切换时,还是点击自定义指示点跳转时?
- “偶尔”的复现概率,是否与页面停留时长、页面切换有关。
-
复现步骤不清晰。当前“复现步骤”一栏只是把代码重新粘贴了一遍,没有可操作的复现步骤。请补充:具体在哪个端复现(App 真机运行/自定义基座/正式包、H5、还是某家小程序);从进入页面到出现现象的具体操作过程。“手机OS平台”填了“全部”,但厂商只填了华为,请明确实际复现的端。另外手机OS系统版本号、手机设备机型目前为空,请补充。
-
缺少“预期结果”和“实际结果”。预期结果应描述轮播应平滑切换、指示点正常联动;实际结果应描述当前异常表现。
-
代码示例缺少页面级上下文。该组件被放在什么页面中使用?该页面在 pages.json 中是否配置了下拉刷新(pullToRefresh)?页面内是否还有其他滚动容器?这些信息对定位 swiper 卡顿类问题很关键。
-
提醒:我无法识别附件,如有录屏、日志等,请以文字形式描述关键现象和数据。
二、bug 是否成立的分析
基于现有信息,暂时无法确认该 bug 成立:
-
知识库中未检索到与你描述的现象(swiper 自动轮播时“一卡一卡/一闪一闪”)直接对应的官方文档说明或已确认的缺陷记录。
-
ISSUE 系统中有一条相关线索:有开发者报告“4.24 以后的版本,下拉刷新和 swiper 同时存在时,swiper 左右滑动卡顿,会卡在两个 swiper-item 中间,不会触发 touchend”(状态:待确认)。该 issue 处于待确认状态,只能说明有人报告过类似卡顿现象,不能作为问题已确认的依据,且其复现条件(页面同时存在下拉刷新)在你的反馈中未体现。如果你的页面配置了下拉刷新,请在补充信息时明确说明。详见 ISSUE 系统:https://issues.dcloud.net.cn/pages/issues/detail?id=17562
-
你的代码中存在一个值得排查的使用模式:swiper 同时绑定了
:current="bannerCur",又在@change回调中回写bannerCur.value。自动轮播每次切换都会形成“change → 更新 bannerCur → current 属性变化”的循环。ask 社区有使用相同模式(current 绑定索引 + change 回写)后出现 swiper 索引异常的案例(发生在微信小程序端,现象是切换应用后索引反复错乱,与你的现象不完全相同,但使用模式一致):https://ask.dcloud.net.cn/question/155764。请在补充反馈时一并说明:指示点的“一闪一闪”是否与 bannerCur 的回写时机相关(例如指示点先变化、画面随后才动,或画面回弹后指示点又跳回)。 -
顺带指出代码中的一处小问题(与该现象可能无关,但建议修正):
defineEmits(["clsoeBanner"])中事件名 "clsoeBanner" 疑似拼写错误(应为 closeBanner),需与父组件监听的事件名保持一致。
三、需要你补充的信息
为便于官方人员复现和定位,请补充:
- 实际复现的端与设备(App Android/iOS 具体机型和系统版本,或 H5/小程序及基础库版本);
- 具体复现操作步骤和复现概率;
- “一闪一闪”的具体表现及触发时机(自动轮播/手动滑动/点击指示点);
- 页面是否配置了下拉刷新、是否有嵌套滚动容器;
- 预期结果与实际结果;
- HBuilderX 版本号请再次确认(当前填写 5.24)。
补充以上信息后,官方人员才能进一步判断该 bug 是否成立并跟进处理。如需继续跟进此问题,建议在 ask 社区发帖交流:https://ask.dcloud.net.cn/