用vue写手机端页面的时候使用到了better-scroll来替换原生的scroll,不过在封装插件的时候发现滚动不了,检查官方api和代码都没有发现问题
以下是源代码Scroll.vue:
<template>
<div class="wrapper" ref="wrapper">
<div class="scrollcontent">
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from "@better-scroll/core";
import Pullup from "@better-scroll/pull-up";
BScroll.use(Pullup);
export default {
name: "Scroll",
data() {
return {
scroll: null
};
},
methods: {
init() {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.wrapper, {
click: true
});
});
}
},
mounted() {
this.init();
},
beforeDestroy() {
this.scroll.destroy();
}
};
</script>
<style scoped></style>
页面数据在created中拿到了,在mounted中使用BScroll,逻辑上也没有问题,wrapper的高度和样式都在父组件中设置好了,在控制台查看element也发现组件内容已经挂载上去了,后来偶然发现修改Scroll.vue的代码保存后页面自动刷新后就能正常使用了,联系vue是局部更新,于是就去网上查了一下,找到了解决方案
修改后的代码:
<template>
<div class="wrapper" ref="wrapper">
<div class="scrollcontent">
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from "@better-scroll/core";
import Pullup from "@better-scroll/pull-up";
BScroll.use(Pullup);
export default {
name: "Scroll",
data() {
return {
scroll: null
};
},
methods: {
init() {
this.$nextTick(() => {
this.scroll = new BScroll(this.$refs.wrapper, {
click: true
});
});
}
},
mounted() {
this.init();
setTimeout(() => {
this.$nextTick(() => {
this.scroll.refresh();
});
}, 500);
},
beforeDestroy() {
this.scroll.destroy();
}
};
</script>
<style scoped></style>
可以看到添加了refresh方法后就能正常使用了,下面是官方的api说明
按理说创建BScroll实例已经放在了nextTick方法中,refresh的功能显得有点多余,但是尝试过各种方法后发现必须调用refresh才能正常滚动,具体原因还不知道,猜测是异步请求数据引起的,以后发现了再来更新
2022.7.26更新:
bscroll配置都正确但是无法滚动,原因很有可能是在bscroll对象创建之后,组件内部包裹的div图片之类或者子组件还未创建,这个时候组件的高度就无法确定,造成滚动异常。
better-scroll在2.x版本以后,可以使用observe-dom
参数来监听内部元素变化,并自动调用refresh方法
官方解释:
开启对 content 以及 content 子元素 DOM 改变的探测。当插件被使用后,当这些 DOM 元素发生变化时,将会触发
scroll 的 refresh 方法。 observe-dom 插件具有以下几个特性:
针对改变频繁的 CSS 属性,增加 debounce
如果改变发生在 scroll 动画过程中,则不会触发 refresh
安装:
npm install @better-scroll/observe-dom --save
使用:
import BScroll from '@better-scroll/core'
import ObserveDOM from '@better-scroll/observe-dom'
BScroll.use(ObserveDOM)
new BScroll('.bs-wrapper', {
//...
observeDOM: true // 开启 observe-dom 插件
})
注意:
由于插件的内部实现使用的是 MutationObserver,它无法探测到 img 标签的是否加载完成。可以结合2.1版本新增的observe-image
参数来修复。