前提说明:为了降低阅读负担,以下只贴出关键代码,读者可参考着改
1、修改前的代码:
showList数据来源于后端
<div class="group-item" ref="wrapper"
<ul class="content" v-for="(item, index) in showList">
<li> {{ item.title }}</li>
</ul>
</div>
import {onMounted, nextTick} from 'vue'
onMounted(() => {
bscroll = new Bscroll(wrapper.value, {
scrollY: true,
probeType: 3,
click: true,
pullUpLoad: true,
mouseWheel: true
})
})
不能滑动问题出现的原因分析:
在showList中还没有数据的时候就对scroll进行了实例化,打印一下scroll对象,可以看见此时scrollerHeight的高度是0
很显然这是不对的,因此,在从后端获取数据后,此时showList列表中有了数据,需要对scroll实例refresh,刷新一下其中scrollerHeight属性值
2、修改后的代码如下:
import {onMounted, nextTick,watch} from 'vue'
onMounted(() => {
scroll = new Bscroll(wrapper.value, {
scrollY: true,
probeType: 3,
click: true,
pullUpLoad: true,
mouseWheel: true
})
})
watch(showList, () => {
nextTick(() => {
scroll.value && scroll.value.refresh()
})
}, {
deep: true
})
打印一下scroll对象:可看到scrollHeight的高度变了
至此问题得到解决,列表已经能正常滑动了。
3、问题总结:
better-scroll 对外暴露了一个 BScroll 的类,我们初始化只需要 new 一个类的实例即可。第一个参数就是我们 wrapper 的 DOM 对象,第二个是一些配置参数,具体参考 better-scroll 的文档。
better-scroll 的初始化时机很重要,因为它在初始化的时候,会计算父元素和子元素的高度和宽度,来决定是否可以纵向和横向滚动。因此,我们在初始化它的时候,必须确保父元素和子元素的内容已经正确渲染了。如果子元素或者父元素 DOM 结构发生改变的时候,必须重新调用 scroll.refresh() 方法重新计算来确保滚动效果的正常。所以同学们反馈的 better-scroll 不能滚动的原因多半是初始化 better-scroll 的时机不对,或者是当 DOM 结构发送变化的时候并没有重新计算 better-scroll。
当你展现在页面的数据列表发生变化,从而导致了DOM元素高度的变化,那么就要调用这个方法,否则better-scorll会不正常工作。比如,上拉加载一次数据后,数据被加入到了数据列表,这导致v-for遍历生成的DOM更多,高度也就变高了,这是就需要调用refresh()。如果你只是在获取数据后的回调函数中同步调用这个方法,则无法生效。但是,我们可以利用watch和nextTick。记得开启深度监听,否则可能监听不到。如果你的数据列表是用ref声明的响应式数据,则像下面的代码那样即可;如果你的数据列表是用reactive的数据模型中的属性,则在watch中,要写成getter函数的方式。如果对better scroll还不了解,推荐看一下这篇文章Vue中的better-scroll_@better-scroll/core_Lemon_dingding的博客-CSDN博客