uniapp小程序如何通过虚拟列表配合节流,完成上拉刷新下拉加载,避免页面卡顿,提升性能呢
uniapp小程序如何通过虚拟列表配合节流,完成上拉刷新下拉加载,避免页面卡顿,提升性能呢?
本文将介绍uniapp小程序中如何使用虚拟列表和节流两种技术实现上拉刷新下拉加载功能,同时避免因渲染大量数据导致的页面卡顿问题。
一、虚拟列表
在uniapp小程序开发中,当我们需要渲染大量列表数据时,很容易出现页面卡顿现象。这时候,我们可以使用虚拟列表技术来优化性能。
所谓虚拟列表,就是将所有数据分成可视区域和非可视区域两部分。只有在可视区域内的数据才进行渲染,而不在可视区域内的数据暂不渲染,这样就可以大幅度减少DOM操作次数,提高渲染效率。
在uniapp小程序中,使用uni-app中的uni-scroll-view组件需要在插件市场安装
<template>
<uni-scroll-view :style="{height: height + 'px'}" @scroll="onScroll">
<ul>
<li v-for="(item, index) in visibleData" :key="index">{{ item }}</li>
</ul>
</uni-scroll-view>
</template>
<script>
export default {
data() {
return {
// 总数据
data: [],
// 可视区域高度
height: 0,
// 可视区域顶部数据序号
startIndex: 0,
// 可视区域底部数据序号
endIndex: 0,
// 可视区域数据
visibleData: []
};
},
mounted() {
// 初始化数据
this.initData();
// 监听可视区域高度变化
uni.getSystemInfo({
success: (res) => {
this.height = res.windowHeight;
}
});
},
methods: {
initData() {
// 生成大量数据
for (let i = 0; i < 10000; i++) {
this.data.push(`数据 ${i+1}`);
}
// 初始化可视区域数据
this.visibleData = this.data.slice(0, 30);
this.endIndex = 29;
},
onScroll(e) {
// 滚动事件
const scrollTop = e.detail.scrollTop;
const itemHeight = 50; // 每个数据项高度
const visibleCount = Math.ceil(this.height / itemHeight); // 可见数据项个数
const startIndex = Math.floor(scrollTop / itemHeight); // 开始渲染的数据序号
if (startIndex !== this.startIndex) {
this.startIndex = startIndex;
this.endIndex = this.startIndex + visibleCount - 1;
this.visibleData = this.data.slice(this.startIndex, this.endIndex + 1);
}
}
}
}
</script>
这个示例代码中,我们使用了 uni-scroll-view 组件来包裹列表内容,并在 mounted 钩子函数中初始化了总数据和可视区域高度,并监听了滚动事件。
当用户滚动列表时,我们根据滚动距离和每个数据项的高度,计算出当前可视区域内应该显示的数据范围,并更新 visibleData 数组,并将其进行渲染。这样,只有可视区域内的数据才会被渲染,而不在可视区域内的数据则不会被渲染,从而大大减少了 DOM 操作次数,提高了渲染效率。
二、节流
除了使用虚拟列表来优化渲染效率外,我们还可以使用节流技术来控制函数的执行频率,从而避免频繁操作导致的页面卡顿问题。
在 uniapp 小程序中,我们可以利用 Lodash 库中的 throttle 方法来实现节流。首先,在需要使用节流的页面中安装 Lodash 库:
npm install lodash
然后,在 vue 文件中引入 Lodash 库中的 throttle 方法,并使用该方法对需要进行节流的函数进行包装:
<template>
<view>
<uni-virtual-list :list="list" :item-size="50" :keep-alive="10" class="list">
<view slot="default" class="item">{{ item.text }}</view>
</uni-virtual-list>
</view>
</template>
<script>
import _ from 'lodash'
export default {
data() {
return {
list: [
{ id: 1, text: 'item 1' },
{ id: 2, text: 'item 2' },
...
]
}
},
created() {
this.throttledScrollHandle = _.throttle(this.scrollHandle, 300)
},
methods: {
scrollHandle() {
// 处理滚动事件
}
},
mounted() {
uni.pageScrollTo({ scrollTop: 0 })
uni.pageScrollTo({ scrollTop: 1000 })
uni.$on('pageScroll', this.throttledScrollHandle)
},
destroyed() {
uni.$off('pageScroll', this.throttledScrollHandle)
}
}
</script>
通过以上代码,我们使用 Lodash 库中的 throttle 方法对 scrollHandle 函数进行包装,从而实现了对该函数的节流。在页面挂载时,我们还需要将 scrollHandle 函数绑定到页面滚动事件上,并设置一个间隔时间,以控制函数的执行频率。
三、上拉刷新和下拉加载
在虚拟列表和节流的基础上,我们可以实现上拉刷新和下拉加载功能。这时候,我们需要监听页面的滚动事件,当滚动到页面底部或顶部时,触发相应的操作。
具体实现如下:
<template>
<view>
<uni-virtual-list :list="list" :item-size="50" :keep-alive="10" class="list">
<view slot="default" class="item">{{ item.text }}</view>
</uni-virtual-list>
</view>
</template>
<script>
import _ from 'lodash'
export default {
data() {
return {
list: [
{ id: 1, text: 'item 1' },
{ id: 2, text: 'item 2' },
...
]
}
},
created() {
this.throttledScrollHandle = _.throttle(this.scrollHandle, 300)
},
methods: {
scrollHandle(e) {
const { scrollTop, scrollHeight, windowHeight } = e.detail
if (scrollTop < 10) {
// 上拉刷新
} else if (scrollTop + windowHeight > scrollHeight - 10) {
// 下拉加载
}
}
},
mounted() {
uni.pageScrollTo({ scrollTop: 0 })
uni.$on('pageScroll', this.throttledScrollHandle)
},
destroyed() {
uni.$off('pageScroll', this.throttledScrollHandle)
}
}
</script>
在上述代码中,我们使用页面滚动事件 e.detail 中的 scrollTop、scrollHeight 和 windowHeight 等属性计算出当前页面是否滚动到了底部或顶部,并触发相应的操作,从而实现了上拉刷新和下拉加载功能。
总结
综上所述,通过虚拟列表技术和节流技术的优化,我们可以实现 uniapp 小程序中的上拉刷新和下拉加载功能,并避免因大量数据渲染导致的页面卡顿问题,提升了页面的流畅性和稳定性。