better-scroll是一款重点解决移动端 (已支持PC )各种滚动场景需求的插件。它的核心是借鉴的iscroll的实现,它的API设计基本兼容iscroll ,在iscroll的基础上又扩展了一些feature以及做了一些性能优化。
better-scroll是基于原生JS实现的,不依赖任何框架。它编译后的代码大小是63kb,压缩后是35kb , gzip后仅有9kb,是一款非常轻量的JS lib。
npm install better-scoll--save
1、如果我们想要使用原生的滚动的话
我们想要实现局部滚动的话,怎么实现呢?
<template>
<ul class="content" ...>
</template>
<style scoped>
.content{
height: 150px;
background-color: pink;
/ *overflow: hidden;*/
overflow-y: scroll;//超出高度部分隐藏
}
</style>
结果为
2.我们不想使用原生滚动,因为原生滚动的话,它在移动端跑的时候非常卡顿,所以这个时候我们就可以使用better-scroll
在这之前,我们先来看一下浏览器的滚动原理: 浏览器的滚动条大家都会遇到,当页面内容的高度超过视口高度的时候,会出现纵向滚动条;当页面内容的宽度超过视口宽度的时候,会出现横向滚动条。也就是当我们的视口展示不下内容的时候,会通过滚动条的方式让用户滚动屏幕看到剩余的内容。
BetterScroll 也是一样的原理,我们可以用一张图更直观的感受一下:
绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 BetterScroll 的滚动原理。
现在准备在首页里面可滚动的区域进行重构,因为直接导入会导致组件对better-scroll依赖太强,耦合度太高,所以我们需要自己再封装一层
1、首先:安装better-scroll
npm install better-scoll@1.13.2 --save
2.在components的common中新建scroll,新建Scroll.vue文件
<template>
<div class="wrapper" ref="wrapper">
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
name: "Scroll",
props: {
//probe侦测,0,1都是不侦测实时位置
//2:在手指滚动的过程中侦测,手指离开后的惯性滚动过程中不侦测
//3:只要是滚动,都侦测
probeType: {
type: Number,
default: 0
},
pullUpLoad: {
type: Boolean,
default: false
}
},
data() {
return {
scroll: null,
}
},
mounted() {
// 1.创建BScroll对象
//通过document.querySelector('wrapper')来获取wrapper不是特别好,因为如果有其他的标签设置wrapper,通过这个来获取的就不知道是哪一个了
this.scroll = new BScroll(this.$refs.wrapper, {
//这个click是一个布尔类型,默认值为false,作用是:better-scroll默认会阻止浏览器的原生click事件。
click: true,
probeType: this.probeType,
pullUpLoad: this.pullUpLoad
})
// 2.监听滚动的位置
this.scroll.on('scroll', (position) => {
// console.log(position);
this.$emit('scroll', position)
})
// 3.监听上拉事件(发送网络请求,请求更多页的数据)
this.scroll.on('pullingUp', () => {
//pullUpLoad默认false,这个配置用于做上拉加载功能
this.$emit('pullingUp')
})
},
methods: {
scrollTo(x, y, time=300) {
this.scroll.scrollTo(x, y, time)
},
finishPullUp() {
// 等数据请求完成,并且将新的数据展示出来以后
this.scroll.finishPullUp()
},
getscrollY(){
return this.scroll?this.scroll:0
}
}
}
</script>
<style scoped>
</style>
注:其中ref如果是绑定在组件中的,那么通过this. $ refs.refname获取到的是一个组件对象。
ref如果是绑定在普通的元素中,那么通过this.$refs.refname获取到的是一个元素对象。
3、然后将这个组件导入到Home.vue中,注册,使用,
<scroll class="content">
<home-swiper :banners="banners"></home-swiper>
<recommend-view :recommends="recommends"></recommend-view>
<feature-view></feature-view>
<tab-control :titles="['流行','新款','精选']" @tabClick="tabClick"
></tab-control>
<goods-list :goods="showGoods"></goods-list>
</scroll>
其中一定要给scroll标签一个高度值,新建class,再到样式里面设置高度
.content {
background-color: #fff;
overflow: hidden;
position: absolute;
top: 44px;
bottom: 49px;
left: 0;
right: 0;
}
结果如下:
但是出现了一个问题:
我们发现TabControl不起作用,原因是现在已经不是原生的滚动了,现在用的是Better-scroll滚动,系统是没有办法帮我们检查这个TabControl滚到了哪里,我们之后再讨论这个怎么做。