Baru-baru ini saya sedang mengusahakan
微信小程序
daripada直播模块
Fungsi bilik sembang dalam modul dipaparkan dalam bentukscroll-view 一维数组
, dan tidak ada pengoptimuman. , menghasilkan pengalaman pengguna yang agak lemah
Mula-mula simulasi situasi 聊天室
sebelum pengoptimuman
Kesakitan boleh dilihat oleh orang bogel eye~
Tetapi pengoptimuman masih perlu dilakukan tanpa pengoptimuman Tetapi sebelum memulakan, saya rasa perlu untuk membahagikan langkah pengoptimuman kepada dua perkara berikut?
2 Memproses sejumlah besar data1 . Tidak lagi menggunakan untuk menetapkan titik utama
Memandangkan versi lama dilaksanakan dalam bentukscroll-into-view
, ini menyebabkan halaman sentiasa dipaparkan selepas data ditambah dan bukannya
scroll-view 一维数组
, jadi pembangun sebelumnya menggunakan atribut加载后的最后一条信息
sebagai加载前的最后一条信息
selepas data dimuatkan Namun, memandangkan penukaranscroll-into-view
dan回位锚点
tidak berlaku secara serentak. ini mengakibatkan fenomena锚点指向
数据加载
回弹
3. Pemprosesan fungsi tambahanOleh kerana ia adalah fungsi , tidak dapat dielakkan untuk memuatkan sejumlah besar perbualan pengguna, gambar, dsb. kandungan, dan kerana
sendiri tidak sesuai untuk memuatkan sejumlah besar data (saya terlalu teruk untuk memikirkan cara lain), jadi saya perlu bekerja keras pada pemuatan dan paparan data
聊天室
scroll-view
1. Invert scroll-viewMengapa kita perlu menyongsangkanBilik sembang pada asalnya mempunyai dan fungsi lain, jadi selepas pengoptimuman selesai, fungsi asal tidak boleh diabaikan
返回底部
OK untuk bermula~
, kemudian jika perlu Untuk sepenuhnya selesaikan masalah ini, kita perlu bermula dari punca masalah scroll-view
数据加载后无法显示后面数据
scroll-into-view
Pertama sekali, kod scroll-view
?
修改前
<view>这是一个直播画面</view> <scroll-view> <view> {{ item.data }} </view> </scroll-view>
const scrollIntoView = ref("index1"); const upper = () => { let lastNum = scrollData.value[0].data; let newArr = []; for (let index = 1; index { scrollIntoView.value = `index${lastNum}`; console.log("scrollIntoView :>>", scrollIntoView.value); }, 100); }; const getRandomColor = () => { return "#" + Math.random().toString(16).substr(2, 6); };
Mula-mula kita perlu menggunakan atribut 倒置scroll-view
kepada
juga, perkara yang paling penting ialah, jika anda mengalih keluar atribut scroll-view
pada transform:rotate(180deg)
, adakah anda akan mendapat kesan ini? 🎜> dan kedudukan 存放数据的数组
pada masa ini Ia berada di sebelah kiri, jika perlu, anda boleh menggunakan atribut scroll-view
untuk mengalih keluarnya, atau mensimulasikannya sendiri scroll-into-view
Langkah seterusnya ialah .
Pada masa ini 滚动条
kami berada dalam keadaan CSS
, yang bermaksud 去除滚动条的CSS样式
(berbelit lidah diketepikan), jadi
::-webkit-scrollbar { display:none; width:0; height:0; color:transparent; }
第一步
如何下拉加载数据
Berikut ialah yang semasascroll-view
Kelihatan jauh lebih baik倒置
顶部是底,底部才是顶
scrolltoupper触顶方法
scrolltolower触底方法
回弹问题
后,就需要考虑如何处理大量数据
。由于uni-app
官方也在文档中提到scroll-view
加载大批量数据的时候性能较差,但无奈手头上也没有别的办法,只能死马当活马医了我第一个想法就是非常经典的虚拟列表
,但是此前所看的很多关于虚拟列表的文章都是在web端
实现的,似乎小程序领域里并不是一个被经常采用的方法,但是所幸还是找到了如何在微信小程序实现虚拟列表
的资料,详情可以查看这篇文章?微信小程序虚拟列表
OK说干就干,那么第一步就是要明确实现虚拟列表需要什么样的数据结构
,虚拟列表其实简单地说就是当某一个模块的数据超出了可视范围就将其隐藏
,那么如何将数据分为多个模块呢?答案就是二维数组
首先将当前的页码
存储起来(默认为0),当触发下拉加载动作时页码+1
,然后以当前页码作为下标
存入数组
const currentShowPage=ref(0) const upper = () => { let len = scrollData.value[currentShowPage.value].length - 1; let lastNum = scrollData.value[currentShowPage.value][len].data; let newArr = []; currentShowPage.value += 1; for (let index = 1; index <p>当然别忘了在页面中也需要以<code>二维数组</code>的形式循环数据</p><pre class="brush:php;toolbar:false"><scroll-view> <view> <view> {{ item.data }} </view> </view> </scroll-view>
数据结构
的问题解决了,那么接下来就是如何判断数据模块是否超出可视范围
。首先我们需要知道每个数据模块的高度
,其实很简单,只需要为每个模块定义一个id
,然后在数据展示之后根据id
获取到该模块的节点信息
然后按顺序存储到数组中
即可
const pagesHeight = [] onReady(()=>{ setPageHeight() }) const upper = () => { ... nextTick(() => { // 每次获取新数据都调用一下 setPageHeight(); }); }; const setPageHeight = () => { let query = uni.createSelectorQuery(); query .select(`#item-${currentShowPage.value}`) .boundingClientRect(res => { pagesHeight[currentShowPage.value] = res && res.height; }) .exec(); };
OK,现在我们已经知道每个模块的高度
了,然后就是监听模块与可视窗口的交叉范围
。这里有两种方法,一种是JS获取可视窗口的高度与模块scrollTop进行差值计算
,另一种是使用小程序的createIntersectionObserver方法让程序自行监听交叉区域
这里我展示的是第二种方法,如果对第一种方法感兴趣的朋友可以向上看第二章开头我推荐的《微信小程序虚拟列表》文章
关于createIntersectionObserver方法
的使用其实很简单,我们只需要把可视窗口的id
以及需要监听的模块id
传入即可,详情看官方文档
onReady(() => { ... observer(currentShowPage.value); }); const upper = () => { ... nextTick(() => { // 每次获取新数据都调用一下 observer(); }); }; // 允许渲染的数组下标,需要设置默认值 const visiblePagesList = ref([-1,0,1]) const observer = pageNum => { const observeView = wx .createIntersectionObserver() .relativeTo("#scroll", { top: 0, bottom: 0 }); observeView.observe(`#item-${pageNum}`, res => { if (res.intersectionRatio > 0) visiblePagesList.value = [pageNum - 1, pageNum, pageNum + 1]; }); };
最后就是在页面中判断该模块是否允许被渲染(也就是是否存储在visiblePagesList数组中)
,这里就很简单了,只需要写一个方法在页面中调用即可
<scroll-view> <view> <template> <view> {{ item.data }} </view> </template> <view></view> </view> </scroll-view>
const includePage = index => { return visiblePagesList.value.indexOf(index) > -1; };
来看看效果如何
额...似乎没有太大区别,那我们看看页面结构到底也没有将可视区域外的内容切换为空白view
成功!
聊天室原本还有回底功能
等,也不能忘了加上
这个部分就比较简单了,只需要直接使用scroll-view
的scroll-top属性
,然后通过在scroll回调中动态记载scroll-top的值即可
下面是部分代码
<scroll-view> ... </scroll-view> <view>回底</view>
let scrollTop; const currentTop = ref(0); const showGoBottom = ref(false); const handle_scroll = throttle(event => { scrollTop = event[0].detail.scrollTop; if (scrollTop > 300) { showGoBottom.value = true; } }, 100); const handle_goBottom = () => { currentTop.value = scrollTop; nextTick(() => { currentTop.value = 0; }); showGoBottom.value = false; };
大功告成~
最后附上demo仓库
https://gitee.com/huang-qihao123/virtual-list-demo
推荐:《uniapp教程》
Atas ialah kandungan terperinci Mari kita bincangkan tentang pemuatan lungsur turun paparan skrol uniapp. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!