vue3长列表优化,使用vue-virtual-scroller实现直播间弹幕列表虚拟滚动效果
使用的组件库是:https://github.com/Akryum/vue-virtual-scroller
官方文档:vue-virtual-scroller
安装依赖
npm install --save vue-virtual-scroller@nextpnpm install --save vue-virtual-scroller@nextyarn add vue-virtual-scroller@next
组件导入
在main.ts中导入组件,这个依赖库支持RecycleScroller,DynamicScroller,DynamicScrollerItem三个组件,可以全量导入,也可以部分导入。这三个组件区别是滚动每一项高度是固定的还是动态的,Recycle就是固定的高度,Dynamic是动态的,动态的话,必须要包含DynamicScrollerItem。
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
import VirtualScroller from 'vue-virtual-scroller'app.use(VirtualScroller)
使用试试
使用固定高度的RecycleScroller组件:
<template><RecycleScrollerclass="scroller":items="list":item-size="32"key-field="id"v-slot="{ item }"><div class="user">{{ item.name }}</div></RecycleScroller>
</template><script>
export default {props: {list: Array,},
}
</script><style scoped>
.scroller {height: 100%;
}.user {height: 32%;padding: 0 12px;display: flex;align-items: center;
}
</style>
使用动态高度的DynamicScroller组件:
注意事项:要结合DynamicScrollerItem一起使用,并且要加上active属性才可以,不然会有警告。
<DynamicScroller:items="messageList":min-item-size="32"class="liveMeg"id="liveMsg"ref="liveMsg"v-if="messageList.length"><template v-slot="{ item, active }"><DynamicScrollerItem:item="item":active="active"class="msgBox":size-dependencies="[item.name, item.msg]":data-index="item.id"><div class="content"><span class="name">{{ item.name }}:</span><span class="msg">{{ item.msg }}</span></div></DynamicScrollerItem></template></DynamicScroller>css样式:
.liveMeg {flex: 1;margin-left: 10px;background-color: #252632;border-radius: 10px;box-shadow: 0 0 10px 2px gray;scrollbar-color: #363741 transparent;scrollbar-width: thin;overflow-y: scroll;.msgBox {display: flex;flex-direction: row;padding: 5px;white-space: wrap;.name {color: #8ce7ff;margin-right: 2px;white-space: nowrap;}.msg {color: white;white-space: wrap;}}}
没使用之前页面会渲染超级多个div元素,但是使用这个虚拟列表之后,就只会渲染在视窗里面的元素:页面中元素数量一直就是这多,超过了就不会渲染出来
自动滚动到底部
想要让消息内容自动滚动到底部,适用于直播间弹幕消息或者聊天消息等结构,可以尝试使用这种方式。但是需要注意:获取DynamicScroller这个组件的时候,要使用document.getElementById('liveMsg')这种形式,不能使用ref这种,因为ref获取到的并不是一个html元素,没有scrollTop方法,所以无法滚动到底部。
// 滚动盒子到底部if (liveMsg.value) {const msgDom: HTMLElement | null = document.getElementById('liveMsg')console.log('liveMsg.value--', msgDom)if (msgDom) {msgDom.scrollTop = msgDom.scrollHeight}}
我这就是在收到message消息的时候就执行这个滚动的方法:
最后实现的抖音直播间的弹幕滚动效果:
开源地址:GitHub - Sjj1024/LiveBox: livebox