uni-app 安卓列表数据减少时会有明显的回收闪烁

uni-app 安卓列表数据减少时会有明显的回收闪烁

开发环境 版本号 项目创建方式
Windows 10 HBuilderX
产品分类:uniapp/App

PC开发环境操作系统:Windows

PC开发环境操作系统版本号:window10家庭版

HBuilderX类型:正式

HBuilderX版本号:3.4.7

手机系统:Android

手机系统版本号:Android 12

手机厂商:小米

手机机型:redmi9

页面类型:nvue

vue版本:vue2

打包方式:云端

项目创建方式:HBuilderX

### 示例代码:

```html
<template>  
<view class="flex-1">  
<scroll-view  
class="flex-1"  
scroll-y="true"  
scrollIntoView="scrollIntoView"
  [@scroll](/user/scroll)="scrollHandler"  
<p>key="count"</p>
<blockquote>
<p><view
class=""
style="height: 150px;"
[@click](/user/click)="count = count === 19 ? 2 : 19"
点击修改item数量 会有明显的减少闪烁,item样式越复杂越明显</view></p>
</blockquote>
<p><view
class="swiper-item"  
id="'item' + item"
    v-for="item in count"  
key="item"
  ><br>
    <text>12121dsfsd</text><br>
    <text>sdfsdfsf</text><br>
    <text>sdfsdfsdfsd</text><br>
    <text>{{ item }}</text><br>
  </view></p>
</scroll-view>
</view>
</template>  
<script>
export default {
data() {
return {
scrollIntoView: '',
navTop: 0,
count: 19
};
},
methods: {
scrollHandler(e) {
const n = 50 / 1650;
const navTop = n * e.detail.scrollTop;
this.navTop = navTop >= 50 ? 50 : navTop;
},
gotoA() {
this.scrollIntoView = '';
this.$nextTick(() => {
this.scrollIntoView = 'item1';
});
}
}
};
</script>  
<style>
page {
height: 100% !important;
overflow: hidden;
display: flex;
flex-direction: column;
}
.flex-1 {
flex: 1;
overflow: hidden;
}
.swiper-item {
/* height: 150px; */
}
</style> 

操作步骤:

  • 当DOM减少的时候 会有很明显的闪烁,看起来像是一个一个删除的样子

预期结果:

  • 不需要一个一个减少,一下子减少就好

实际结果:

  • 一个一个依次减少

bug描述:

  • 当DOM减少的时候 会有很明显的闪烁,看起来像是一个一个删除的样子
8 回复
<template> <view class="flex-1"> <scroll-view class="flex-1" scroll-y="true" :scrollIntoView="scrollIntoView" @scroll="scrollHandler" > <view class="" style="height: 150px;align-items: center;justify-content: center;" @click="count = count === 50 ? 2 : 50" >点击修改item数量 会有明显的减少闪烁,item样式越复杂越明显</view >
  <view  
    class="swiper-item"  
    :id="'item' + item"  
    v-for="item in count"  
    :key="item"  
  >  
    <text>{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}</text>  
    <text>{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}</text>  
    <text>{{ item }}{{ item }}{{ item }}{{ item }}</text>  
    <text>{{ item }}{{ item }}{{ item }}{{ item }}{{ item }}</text>  
  </view>  
</scroll-view>  
</view> </template> <script> export default { data() { return { scrollIntoView: '', navTop: 0, count: 50 }; }, methods: { scrollHandler(e) { const n = 50 / 1650; const navTop = n * e.detail.scrollTop; this.navTop = navTop >= 50 ? 50 : navTop; }, gotoA() { this.scrollIntoView = ''; this.$nextTick(() => { this.scrollIntoView = 'item1'; }); } } }; </script> <style> page { height: 100% !important; overflow: hidden; display: flex; flex-direction: column; } .flex-1 { flex: 1; overflow: hidden; } .swiper-item { /* height: 150px; */ background-color: #f00; margin-bottom: 10rpx; } </style>

后续会排查优化,先尝试将 nvueStyleCompiler 设置为 weex:https://uniapp.dcloud.io/collocation/manifest.html#app-plus

不太行 weex模式 样式全乱了

HBuilderX alpha 3.4.10+ 已经修复

这个问题并没有修复啊,为什么我的目前还是一样的问题

回复 5***@qq.com: 经反复测试,只要引入uni-rate组件之后 就会有闪烁现象,不引入则没有

在 Uni-App 中,当安卓列表数据减少时出现明显的回收闪烁问题,通常是由于列表项的复用机制导致的。以下是一些可能的解决方案:

1. 使用 key 属性

为列表项添加唯一的 key 属性,可以帮助 Vue 更好地跟踪每个列表项的变化,从而减少不必要的 DOM 操作。

<template>
  <view>
    <view v-for="(item, index) in list" :key="item.id">
      {{ item.name }}
    </view>
  </view>
</template>

2. 使用 uni-list 组件

Uni-App 提供了 uni-list 组件,它内部已经优化了列表的渲染和更新,可以减少闪烁问题。

<template>
  <view>
    <uni-list>
      <uni-list-item v-for="(item, index) in list" :key="item.id" :title="item.name" />
    </uni-list>
  </view>
</template>

3. 使用 v-if 控制列表渲染

在数据更新时,使用 v-if 控制列表的渲染,确保列表在数据更新完成后再重新渲染。

<template>
  <view>
    <view v-if="list.length > 0">
      <view v-for="(item, index) in list" :key="item.id">
        {{ item.name }}
      </view>
    </view>
  </view>
</template>

4. 使用 uni.$emituni.$on 进行数据更新

通过事件机制来更新列表数据,确保数据更新时不会直接操作 DOM,从而减少闪烁。

// 在父组件中
uni.$emit('updateList', newList);

// 在子组件中
uni.$on('updateList', (newList) => {
  this.list = newList;
});

5. 使用 uni.$nextTick 延迟更新

在数据更新后,使用 uni.$nextTick 延迟 DOM 更新,确保数据更新完成后再进行渲染。

this.list = newList;
uni.$nextTick(() => {
  // 数据更新完成后的操作
});

6. 使用 uni-listscroll-view 组件

如果列表数据较多,可以使用 scroll-view 组件来优化列表的渲染和滚动性能。

<template>
  <view>
    <scroll-view scroll-y="true" style="height: 100vh;">
      <view v-for="(item, index) in list" :key="item.id">
        {{ item.name }}
      </view>
    </scroll-view>
  </view>
</template>

7. 使用 uni-listvirtual-list 组件

对于超长列表,可以使用 virtual-list 组件来优化性能,减少 DOM 操作。

<template>
  <view>
    <virtual-list :list="list" :item-height="50">
      <template v-slot:default="{ item }">
        <view>{{ item.name }}</view>
      </template>
    </virtual-list>
  </view>
</template>

8. 使用 uni-listrecycle-list 组件

recycle-list 组件可以复用列表项,减少 DOM 操作,从而减少闪烁。

<template>
  <view>
    <recycle-list :list="list" :item-height="50">
      <template v-slot:default="{ item }">
        <view>{{ item.name }}</view>
      </template>
    </recycle-list>
  </view>
</template>
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!