一、better-scroll介绍
better-scroll 是一款重点解决移动端(已支持 PC)各种滚动场景需求的插件。它的核心是借鉴的 iscroll 的实现,它的 API 设计基本兼容 iscroll,在 iscroll 的基础上又扩展了一些 feature 以及做了一些性能优化。
better-scroll 是基于原生 JS 实现的,不依赖任何框架。它编译后的代码大小是 63kb,压缩后是 35kb,gzip 后仅有 9kb,是一款非常轻量的 JS lib。
文档来源:http://ustbhuangyi.github.io/better-scroll/doc/zh-hans/
绿色部分为 wrapper,也就是父容器,它会有固定的高度。黄色部分为 content,它是父容器的第一个子元素,它的高度会随着内容的大小而撑高。那么,当 content 的高度不超过父容器的高度,是不能滚动的,而它一旦超过了父容器的高度,我们就可以滚动内容区了,这就是 better-scroll 的滚动原理。
二、引入better-scroll
我的项目vue-cli构建的
所以先安装插件,npm install -S better-scroll
如果嫌下载慢可以使用淘宝镜像cnpm install -S better-scroll
接下来在项目components文件夹创建组件Scroll.vue
给 tap,probeType 赋值
当然better-scroll还有好多选项
<template>
<div class="wrapper" ref="wrapper">
<slot></slot>
</div>
</template>
<script>
import BScroll from 'better-scroll'
export default {
// 组件名
name: 'Scroller',
// 父组件自定义的事件
props:{
handleToScroll : {
type: Function,
default : function(){}
},
handleToTouchEnd : {
type: Function,
default: function(){}
}
},
mounted () {
// 定义一个scroll变量,将BScroll对象赋值,ref是为操作dom元素的属性,通过$refs调用wrapper这个div
var scroll = new BScroll(this.$refs.wrapper,{
tap : true,
probeType: 1
});
this.scroll = scroll;
// 监听自定义的事件
scroll.on('scroll',(pos) => {
this.handleToScroll(pos)
});
scroll.on('touchEnd', (pos) => {
this.handleToTouchEnd(pos)
})
},
methods: {
// 滚动到指定的位置
toScrollTop(y){
this.scroll.scrollTo(0,y);
}
}
}
</script>
<style scoped>
.wrapper{
height: 100%;
}
</style>
再去main.js文件去引入注册
//引入
import Scroller from './components/Scroller'
//注册
Vue.component('Scroller' , Scroller)
三、使用better-scroll
在views文件夹下创建一个test.vue,测试一下效果
<template>
<div class="test">
<div class="box">
<Scroller :handleToScroll="handleToScroll" :handleToTouchEnd="handleToTouchEnd" ref="list">
<div class="item" ref="test">
<ul >
<li class="pullDown">{{ pullDownMsg }}</li>
<li v-for="(item,index) in 15" :key="index">
<h2 style="height:30px;background:#ccc;">{{index}}</h2>
<p v-for="(v,index) in 30" :key="index">{{v}}</p>
</li>
</ul>
</div>
</Scroller>
</div>
<div class="index">
<ul>
<li v-for="(item,index) in 15" :key="index" @touchstart="handleToIndex(index)">{{index}}</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name : 'Test',
data(){
return {
pullDownMsg: ''
}
},
activated(){
setTimeout(()=>{
this.isLoading = false;
},1000)
},
methods: {
handleToScroll(pos){
if( pos.y > 30 ){
this.pullDownMsg = '正在更新中';
}
},
// 下拉结束,更新页面数据,将下拉消息清空
handleToTouchEnd(pos){
if( pos.y > 30 ){
window.location.reload();//重新加载页面
this.pullDownMsg = '更新成功';
setTimeout(()=>{
this.movieList = res.data.data.movieList;
this.pullDownMsg = '';
},1000);
}
},
handleToIndex (index) {
// console.log(index)
var h2 = this.$refs.test.getElementsByTagName('h2')
// 原生的方法
// this.$refs.city_sort.parentNode.scrollTop = h2[index].offsetTop
// better-scroll 的方法
this.$refs.list.toScrollTop(-h2[index].offsetTop);
}
}
}
</script>
<style scoped>
.test{
display: flex;
height:100%;
width: 100%;
}
.box{
height: 617px;
flex: 1;
}
.item{
border-bottom: 1px solid #ddd;
}
.index{
width:20px;
display: flex;
flex-direction:column;
justify-content:center;
text-align: center;
}
</style>