better-scroll
1.实时监听滚动位置 — on 方法
2.头部和尾部弹性滚动,上拉触发事件
3.原生滚动:也是需要一个 wapper 设置高度,让 overflow-y:scroll 就OK了。但是原生滚动比较卡顿,也做不到头部和尾部弹性滚动。
1 基本使用
BetterSroll 2.x 有基础滚动 和 增强型滚动(需要引入额外插件) 和全能力滚动。全能力滚动提供了一个拥有全部插件能力的 BetterScroll 包,不需要导入各种插件,之后介绍的是全能力滚动的使用。
1.安装 better-scroll
最开始安装的是 better-scroll 2.x,一直没法滚动!!!换成第1.x好了。后来发现原因是在 chrom 浏览器上面手机调试要刷新一下,better-scroll 2.x 才可以滑动。解决方法
1 | npm install @better-scroll/core@next --save //2.x |
2.Dom 结构
wapper 是滚动的区域,content 是滚动的内容而且只能哟一个 content,wapper 设置高度并且小于content 才会滑动。
1 | //wrapper 的高度或者宽度 大于 content 的高度或者宽度,才可以滚动 |
3.导入 better-scroll,在 mounted 函数里面创建 BScroll 对象(2.x的引入有所不同,参考官方文档)
1 | import BScroll from 'better-scroll' |
1.1 常用配置项 和 事件
1) 配置项
1 | // 0,1都是不侦测实时的位置 |
2) 事件(mounted函数内实现)
- scroll,在屏幕滚动的时候默认参数是屏幕的坐标。
- pullingUp,上拉加载动作后触发,一般用来请求数据。但是这个事件只会执行一次上拉加载,需要配合使用 finishPullUp() 方法告诉 better-scroll 数据已加载。在组件中,finishPullUp 应在数据请求之后调用。
- refresh() :重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
- scrollTo(x, y, time, easing):滚动到指定的位置。
1 | // 监听滚动事件 |
2 better-scroll 的 DOM 组织
better-scroll 中的 content 和 wrapper :
wrapper :就是可以滚动的范围,一般是屏幕的一部分,高度是小于或者等于 100vh
content:就是需要滚动的元素范围,大于 wrapper
将 better-scroll 封装在组件中,因为要在组件里新建一个 BS 对象,所以组件里面必要要有 wrapper 的DOM。一般滚动元素会自动撑高content ,content 会自动撑高 wrapper,wrapper 和 content 的高度是一样,就无法滚动。
1 | <template> |
wrapper 的高度和 wrapper 的父级、视口页面的根元素有关,比如 Home 中用了 better-scroll 组件,wrapper 的父级就是id="home"
的 div 元素。让父元素占据100vh,wrapper 本身根据 calc 函数/position定位得到一个可滚动的范围。
1 | <template> |
如果 better-scroll 是整个视口页面的子组件的子组件,要确定 wrapper 高度,依然还是只需要确定 better-scroll 的高度是一个可滚动范围。比如 home 是100vh,list 是100%, better-scroll 自己调整滚动范围。
1 | <template> |
总之,wrapper 的高度滚动视口的高度,一般 wrapper 需要 overflow: hidden;
,content 是滚动元素的高度
3 封装 scroll 组件
3.1暴露的接口
在 mounted 声明周期函数中 初始化 Better-scroll 对象,需要暴露的接口有:probeType、pullUpLoad以及data 。data 是指父组件传给 scroll 内部的会发生变化数据,通过watch 监听data,一旦数据发生变化,重新计算 bs 高度。
1 | props:{ |
这里的 data 是一个数组对象。
1 | :data="[swiperImages, product, shopInfo, detailGoods, itemParams, commentInfo, recommendInfo]" |
3.2 封装 bs 自带的方法
为了让父元素更方便调用 bs 自带方法,进行封装。
1 | __initScroll() { |
3.3 父组件使用 scroll 对象
- 动态绑定接口
- 通过 $refs 获取 bs 对象,从而调用封装的方法和数据
3.4 better-scroll 在 vue 使用的bug
主要问题
better-scroll 滚动的原理是利用了 translate 属性,因此位于 wrapper 区域的定位会失效。解决方法是复制一份定位dom。
better-scroll 会计算出一个 scrollerHeight ,可滚动的高度就是这个数值。图片加载慢,可能在better-scroll计算之前还未加载,这样scrollerHeight 远小于滚动的高度。解决方法就是监听图片的 load 事件,之后通过 refresh() 重新计算。
引申问题
- 父组件通过 $refs 获取 bs 对象的时候,scroll 组件获取不到
初始化的 bs 对象的时候,进行判断 wrapper DOM 是否存在;延迟 20ms 初始化
1 | setTimeout(this.__initScroll, 20); |
封装 bs 方法的时候首先判断 scroll 对象是否存在
1 | this.scroll && this.scroll.refresh(); |
图片 load 事件的防抖
【1】如果需要的监听的图片数量很少,比如轮播图
1 | imageIoad(){ |
【2】debounce 防抖函数
1 | imageLoad() { |
4Vant UI 轮播图
引入组件
1) babel-plugin-import 自动按需导入
2) 自己按需导入
1 | // 按需全局引入 vant组件 |
3)在 man.js 中全局注册后, 直接在组件中使用。也可以在组件中导入 Swipe, SwipeItem 模块,但是此时最好用 babel-plugin-import 插件自动导入 css 文件
1 | <template> |