vue中使用better-scroll2.0的坑
前提我自己封装的一个Scroll组件 比较简单
<template>
<div class="scroll_wrapper" ref="scroll_wrapper">
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from "better-scroll"
export default {
name: "Scroll",
props:{
data: {
type: Object,
default: null
},
},
mounted() {
setTimeout(() => {
this._initScroll()
}, 20)
},
methods:{
//初始化BS
_initScroll(){
if (!this.$refs.scroll_wrapper) {
return
}
this.scroll = new BScroll(this.$refs.scroll_wrapper, {
click:true
})
},
refresh(){
//重新计算BS
this.scroll && this.scroll.refresh()
},
enable() {
// 启用BS
this.scroll && this.scroll.enable()
},
disable(){
//禁用BS
this.scroll&&this.scroll.disable();
},
},
watch: {
// 监听数据的变化,延时refreshDelay时间后调用refresh方法重新计算,保证滚动效果正常
data() {
setTimeout(() => {
this.refresh()
}, 200)
}
}
}
</script>
组件在父组件中的引用是下面这样
<Scroll :data="$data" ref="scroll">
<div class="orders">
<div v-for="(order,index) in allOrders" :key="index" @click="selectOrder(order)" >
<!--内容-->
</div>
</div>
<div class="none"></div>
</Scroll>
进入主题
请求数据并将数据展示出来的列表内容高度是符合BS的,也就是说可以滚动,但是事实并没有滚动,原因在于并没有在请求完数据的时候重新计算BS
这里一定要加上this.$nextTick,不然不起作用
getOrderList(){
let url = "/api/order/client/queryOrderByUserId?userId="+this.$store.state.user.id
this.axios.get(url).then(res=>{
this.allOrders = res.data.data
this.$nextTick(()=>{
this.$refs.scroll.refresh()
})
})
}
注意:请求数据时如果是在created中请求,一定要加上this.$nextTick
created(){
this.$nextTick(()=>{
this.getOrderList()
})
}
如果是在mounted中要这样写
mounted(){
this.getOrderList()
}
不推荐在mounted中获取数据,会有滚动bug(亲测)
第二个就是当页面滚动内容是可变的,但是是没有数据请求的,要实现这样的效果:**当content内容大于外层的wrapper设置的可视内容高度时,就要滚动,当content内容小于外层的wrapper设置的可视内容高度时,就要不滚动。**例如我的项目中
这个页面中商品评价是可以展开的,上图中的content内容是没有大于蓝色部分wrapper的可视内容高度,所以不能滚动。
但是当我点开一个面板时,如下图
这时候content内容高度是大于蓝色部分的可视内容高度,可以滚动。
说明:这里的content高度一定是面板展开结束后的高度,而不是为展开时的高度。所以整个content的高度一定实在面板动画展开结束后计算,这时候就要用到vue中transitionend事件
代码如下
<van-collapse-item :name="index" @transitionend="transitionend" v-for="(product,index) in order.list"/>
methods:{
//当面板展开动画结束后计算滚动内容高度,然后确定是否禁用还是重新计算滚动内容高度
transitionend(){
//内层高度小于外层wrapper的高度 禁用BS
if(this.scrollHeight < this.clientHeight){
this.$nextTick(()=>{
this.$refs.scroll.disable()
})
//内层高度大于外层wrapper的高度 启用BS并重新计算BS高度
}else {
this.$nextTick(()=>{
this.$refs.scroll.enable()
this.$refs.scroll.refresh()
})
}
}
},
computed:{
//Scroll组件中外层wrapper的可视高度,即上面图片中的蓝色区域
clientHeight(){
return this.$refs.scroll.scroll.wrapper.clientHeight
},
//Scroll组件中内层content的可视高度
scrollHeight(){
return this.$refs.scroll.scroll.content.clientHeight
}
}
下面是this.$refs.scroll的打印内容,我把它里面的wrapper和content都打印出来
this.$refs.scroll的内容
this.$refs.scroll.scroll的内容
this.$refs.scroll.scroll.wrapper以及this.$refs.scroll.scroll.content的内容都在this.$refs.scroll.scroll中如下图
- BS外层固定的clientHeight都可以通过
this.$refs.scroll.scroll.wrapper.clientHeight获取 - BS内层滚动内容clientHeight都可以通过
this.$refs.scroll.scroll.content.clientHeight