Better

  • 主页
  • 随笔
所有文章 友链 关于我

Better

  • 主页
  • 随笔

better-scroll 基本使用

2020-07-27

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
2
npm install @better-scroll/core@next --save //2.x
npm install better-scroll --save //1.x

2.Dom 结构

wapper 是滚动的区域,content 是滚动的内容而且只能哟一个 content,wapper 设置高度并且小于content 才会滑动。

1
2
3
4
5
6
7
8
9
//wrapper 的高度或者宽度 大于 content 的高度或者宽度,才可以滚动
<div class="wrapper">
<ul class="content">
<li>...</li>
<li>...</li>
...
</ul>
<!-- content 之外的元素不参与滚动,所以需要将滚动元素放在 content 内 -->
</div>

3.导入 better-scroll,在 mounted 函数里面创建 BScroll 对象(2.x的引入有所不同,参考官方文档)

1
2
3
4
5
6
7
8
9
10
11
import BScroll from 'better-scroll' 
data() {
return {
scroll: null,
};
},
mounted() {
this.scroll = new BScroll(this.$refs.wrapper, {
配置项..
})
}

1.1 常用配置项 和 事件

1) 配置项

1
2
3
4
5
6
7
8
9
10
11
12
13
  // 0,1都是不侦测实时的位置
// 2: 在手指滚动的过程中侦测, 手指离开后的惯性滚动过程中不侦测.
// 3: 只要是滚动, 都侦测
probeType: 3,

// pullup 插件相关配置,true 为开启上拉加载
pullUpLoad:true

// 表单元素点击可以监听,但是 div 等其他元素需要设置为 ture
click: true,

// 鼠标的滚动 也可以当做 手指滑动屏幕
mouseWheel: true,

2) 事件(mounted函数内实现)

  • scroll,在屏幕滚动的时候默认参数是屏幕的坐标。
  • pullingUp,上拉加载动作后触发,一般用来请求数据。但是这个事件只会执行一次上拉加载,需要配合使用 finishPullUp() 方法告诉 better-scroll 数据已加载。在组件中,finishPullUp 应在数据请求之后调用。
  • refresh() :重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
  • scrollTo(x, y, time, easing):滚动到指定的位置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 监听滚动事件
//on方法第一个参数是要检监听的事件,第二个参数是一个函数,其函数返回一个 position(实时位置)
this.scroll.on('scroll',(position) => {
console.log(position);
})
this.scroll.on('pullingUp', () => {
this.$emit('pullingUp')
})

//获取数据
getHomeGoods(type, page).then((res) => {
。。。。
this.$refs.scroll.finishPullUp();
});

2 better-scroll 的 DOM 组织

better-scroll 中的 content 和 wrapper :

  • wrapper :就是可以滚动的范围,一般是屏幕的一部分,高度是小于或者等于 100vh

  • content:就是需要滚动的元素范围,大于 wrapper

将 better-scroll 封装在组件中,因为要在组件里新建一个 BS 对象,所以组件里面必要要有 wrapper 的DOM。一般滚动元素会自动撑高content ,content 会自动撑高 wrapper,wrapper 和 content 的高度是一样,就无法滚动。

1
2
3
4
5
6
7
<template>
<div class="wrapper" ref="wrapper">
<div class="content">
<slot>滚动的内容</slot>
</div>
</div>
</template>

wrapper 的高度和 wrapper 的父级、视口页面的根元素有关,比如 Home 中用了 better-scroll 组件,wrapper 的父级就是id="home" 的 div 元素。让父元素占据100vh,wrapper 本身根据 calc 函数/position定位得到一个可滚动的范围。

1
2
3
4
5
<template>
<div id="home">
<better-scroll >....
</div>
</template>

如果 better-scroll 是整个视口页面的子组件的子组件,要确定 wrapper 高度,依然还是只需要确定 better-scroll 的高度是一个可滚动范围。比如 home 是100vh,list 是100%, better-scroll 自己调整滚动范围。

1
2
3
4
5
6
7
<template>
<div id="home">
<list>
<better-scroll >....
</list>
</div>
</template>

总之,wrapper 的高度滚动视口的高度,一般 wrapper 需要 overflow: hidden;,content 是滚动元素的高度

3 封装 scroll 组件

3.1暴露的接口

在 mounted 声明周期函数中 初始化 Better-scroll 对象,需要暴露的接口有:probeType、pullUpLoad以及data 。data 是指父组件传给 scroll 内部的会发生变化数据,通过watch 监听data,一旦数据发生变化,重新计算 bs 高度。

1
2
3
4
5
6
7
8
9
10
11
12
props:{
data: {
type: Array,
default() {
return [];
},
},},
watch: {
data() {
setTimeout(this.refresh, 20);
},
},

这里的 data 是一个数组对象。

1
:data="[swiperImages, product, shopInfo, detailGoods, itemParams, commentInfo, recommendInfo]"

3.2 封装 bs 自带的方法

为了让父元素更方便调用 bs 自带方法,进行封装。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
__initScroll() {
// 1.初始化BScroll对象
if (!this.$refs.wrapper) return;
this.scroll = new BScroll(this.$refs.wrapper, {
probeType: this.probeType,
click: true,
pullUpLoad: this.pullUpLoad,
mouseWheel: true,
});

// 2.将监听事件回调
this.scroll.on("scroll", (pos) => {
this.$emit("scroll", pos);
});

// 3.监听上拉到底部
this.scroll.on("pullingUp", () => {
console.log("上拉加载");
this.$emit("pullingUp");
});
},
/**
* 封装
* 滚动到指定的位置
*/
scrollTo(x, y, time = 300) {
this.scroll && this.scroll.scrollTo(x, y, time);
},
/**
* 封装
* 刷新,重新计算 滚动高度
*/
refresh() {
this.scroll && this.scroll.refresh();
},
/**
* 封装
* 本次上拉已经结束
*/
finishPullUp() {
this.scroll && this.scroll.finishPullUp();
},

/**
* 返回滚动的 y 轴距离
*/
getScrollY() {
return this.scroll ? this.scroll.y : 0;
},

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
2
3
4
5
6
7
imageIoad(){
// 本来会 emit 4 次 ,此处用 isLoad判断只用一次
if(!this.isLoad) {
this.$emit('swiperImageIoad')
this.isLoad = true
}
}

【2】debounce 防抖函数

1
2
3
imageLoad() {
this.$emit('swiperImageIoad')
},

4Vant UI 轮播图

引入组件

1) babel-plugin-import 自动按需导入

2) 自己按需导入

1
2
3
4
5
6
7
// 按需全局引入 vant组件
import Vue from 'vue'
import { Swipe, SwipeItem } from 'vant'
import 'vant/lib/index.css';


Vue.use(Swipe).use(SwipeItem);

3)在 man.js 中全局注册后, 直接在组件中使用。也可以在组件中导入 Swipe, SwipeItem 模块,但是此时最好用 babel-plugin-import 插件自动导入 css 文件

1
2
3
4
5
6
7
8
9
<template>
<van-swipe :autoplay="3000" indicator-color="white">
<van-swipe-item v-for="(item,index) in banners" :key="index">
<a href="item.link">
<img :src="item.image" alt width="100%" />
</a>
</van-swipe-item>
</van-swipe>
</template>
赏

谢谢你请我吃糖果

  • vue
  • 插件

扫一扫,分享到微信

微信分享二维码
git忽略 本地仓库不上传远程仓库
Vue实战项目 详情页 Detail
© 2020 Better
Hexo Theme Yilia by Litten
  • 所有文章
  • 友链
  • 关于我

tag:

  • css
  • js
  • html
  • Python
  • Numpy
  • Pandas
  • vue
  • uml
  • 框架
  • c++
  • git
  • 工具
  • javaee
  • java
  • leetcode
  • 数据库
  • tensorflow
  • 工具类
  • 网页布局
  • RL
  • more
  • 算法
  • summary
  • 计算机组成原理
  • 软件测试
  • 插件
  • jsp
  • 移动端布局
  • 操作系统
  • 微信小程序
  • 计算机网络
  • hobby
  • 机器学习
  • python

    缺失模块。
    1、请确保node版本大于6.2
    2、在博客根目录(注意不是yilia根目录)执行以下命令:
    npm i hexo-generator-json-content --save

    3、在根目录_config.yml里添加配置:

      jsonContent:
        meta: false
        pages: false
        posts:
          title: true
          date: true
          path: true
          text: false
          raw: false
          content: false
          slug: false
          updated: false
          comments: false
          link: false
          permalink: false
          excerpt: false
          categories: false
          tags: true
    

  • 友情链接1
  • 友情链接2
  • 友情链接3
  • 友情链接4
  • 友情链接5
  • 友情链接6
很惭愧

只做了一点微小的工作
谢谢大家