dasensen
dasensen
  • 发布:2026-10-26 10:55
  • 更新:2026-10-26 10:57
  • 阅读:53

【报Bug】swiperswiper swiper-item组件 卡住一样一闪一闪

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: 64位

HBuilderX类型: 正式

HBuilderX版本号: 5.24

手机系统: 全部

手机厂商: 华为

页面类型: vue

vue版本: vue3

打包方式: 云端

项目创建方式: HBuilderX

测试过的手机:

vivo手机Y76S,微信小程序

示例代码:
<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>

操作步骤:
<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>

预期结果:

预期跟正常的轮播图一样

实际结果:

实际的效果一卡一卡的

bug描述:

偶尔会发生 组件一卡一卡的

2026-10-26 10:55 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

感谢提交这条 bug 反馈。以下以官方评审视角对该反馈进行评审:

一、反馈完整性评审

目前反馈已包含标题、问题描述、代码示例和部分分类信息(Windows 64位、HBuilderX 正式版 5.24、Vue3、手机OS平台“全部”、厂商华为),但存在以下不足,需要补充:

  1. BUG 描述过于简略。“偶尔会发生 组件一卡一卡的”“卡住一样一闪一闪”表述模糊,官方人员难以据此定位。建议补充:

    • “一闪一闪”的具体表现:是切换动画执行到一半被中断回弹?是 swiper-item 画面白屏/跳变?还是自定义指示点先跳再回?
    • 触发时机:出现在自动轮播(autoplay)切换时、手指滑动切换时,还是点击自定义指示点跳转时?
    • “偶尔”的复现概率,是否与页面停留时长、页面切换有关。
  2. 复现步骤不清晰。当前“复现步骤”一栏只是把代码重新粘贴了一遍,没有可操作的复现步骤。请补充:具体在哪个端复现(App 真机运行/自定义基座/正式包、H5、还是某家小程序);从进入页面到出现现象的具体操作过程。“手机OS平台”填了“全部”,但厂商只填了华为,请明确实际复现的端。另外手机OS系统版本号、手机设备机型目前为空,请补充。

  3. 缺少“预期结果”和“实际结果”。预期结果应描述轮播应平滑切换、指示点正常联动;实际结果应描述当前异常表现。

  4. 代码示例缺少页面级上下文。该组件被放在什么页面中使用?该页面在 pages.json 中是否配置了下拉刷新(pullToRefresh)?页面内是否还有其他滚动容器?这些信息对定位 swiper 卡顿类问题很关键。

  5. 提醒:我无法识别附件,如有录屏、日志等,请以文字形式描述关键现象和数据。

二、bug 是否成立的分析

基于现有信息,暂时无法确认该 bug 成立:

  1. 知识库中未检索到与你描述的现象(swiper 自动轮播时“一卡一卡/一闪一闪”)直接对应的官方文档说明或已确认的缺陷记录。

  2. ISSUE 系统中有一条相关线索:有开发者报告“4.24 以后的版本,下拉刷新和 swiper 同时存在时,swiper 左右滑动卡顿,会卡在两个 swiper-item 中间,不会触发 touchend”(状态:待确认)。该 issue 处于待确认状态,只能说明有人报告过类似卡顿现象,不能作为问题已确认的依据,且其复现条件(页面同时存在下拉刷新)在你的反馈中未体现。如果你的页面配置了下拉刷新,请在补充信息时明确说明。详见 ISSUE 系统:https://issues.dcloud.net.cn/pages/issues/detail?id=17562

  3. 你的代码中存在一个值得排查的使用模式:swiper 同时绑定了 :current="bannerCur",又在 @change 回调中回写 bannerCur.value。自动轮播每次切换都会形成“change → 更新 bannerCur → current 属性变化”的循环。ask 社区有使用相同模式(current 绑定索引 + change 回写)后出现 swiper 索引异常的案例(发生在微信小程序端,现象是切换应用后索引反复错乱,与你的现象不完全相同,但使用模式一致):https://ask.dcloud.net.cn/question/155764。请在补充反馈时一并说明:指示点的“一闪一闪”是否与 bannerCur 的回写时机相关(例如指示点先变化、画面随后才动,或画面回弹后指示点又跳回)。

  4. 顺带指出代码中的一处小问题(与该现象可能无关,但建议修正):defineEmits(["clsoeBanner"]) 中事件名 "clsoeBanner" 疑似拼写错误(应为 closeBanner),需与父组件监听的事件名保持一致。

三、需要你补充的信息

为便于官方人员复现和定位,请补充:

  1. 实际复现的端与设备(App Android/iOS 具体机型和系统版本,或 H5/小程序及基础库版本);
  2. 具体复现操作步骤和复现概率;
  3. “一闪一闪”的具体表现及触发时机(自动轮播/手动滑动/点击指示点);
  4. 页面是否配置了下拉刷新、是否有嵌套滚动容器;
  5. 预期结果与实际结果;
  6. HBuilderX 版本号请再次确认(当前填写 5.24)。

补充以上信息后,官方人员才能进一步判断该 bug 是否成立并跟进处理。如需继续跟进此问题,建议在 ask 社区发帖交流:https://ask.dcloud.net.cn/

内容为 AI 生成,仅供参考

要回复问题请先登录或注册