这是我参与更文挑战的第2天,活动详情查看: 更文挑战
前言
在开发小程序的过程中,官方自带的组件scroll-view应该是使用的地方很多了,今天就来看看这个组件的n中常见用法。
官方介绍
尤大说了文档是个好东西!所以在学习任何东西的时候,首先我们需要做的就是认认真真的去看看官方文档介绍,毕竟很多东西都能够从文档上获取到的。这里还是提供一张官方的文档截图,如下:
上面图用红色框起来的可以适当注意下,算是常用的几个。
上图中漏掉了两个常用的bindscrolltoupper、bindscrolltolower
第一种基础用法
这种用法也是最常用的,有两种形式。
定高滚动
给定一个高度,让内容在这个高度内容显示,超出可以滑动显示内容,这里的高度可以是小于页面的高度,也可以刚好是页面的高度。代码如下:
<scroll-view scroll-y="true" class="demo-scroll-block">
<view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
<view>这是测试的文字哦</view>
</view>
</scroll-view>
.demo-scroll-block {
width: 100%;
height: 200rpx;
}
效果如下:
定高下拉更新上拉加载更多
就是在上面的基础上添加上拉加载更多和下拉更新数据的功能。其实就是运用了两个官方的方法而已。
- bindscrolltoupper:滚动到顶部/左边时触发
- bindscrolltolower:滚动到底部/右边时触发
这里就不具体介绍了,主要就是用着两个方法滚动到顶部时,请求接口更新数据,滚动到底部时加载下一页数据。
第二种用法:左右滚动导航
第二种用法也是在做小程序的过程中很常见的用法了,直接上代码:
<scroll-view scroll-x="true" class="demo-scroll-nav">
<view class="nav-wrapper">
<text class="{{navIndex == index ? 'active':''}}" wx:for="{{navArr}}" wx:key="unique" bindtap="navChange" data-index="{{index}}">{{item}}</text>
</view>
</scroll-view>
navArr:['指南','框架','组件','API','服务端','工具','云开发','扩展能力','更新日志'],
navIndex:0,
navChange(e){
this.setData({
navIndex:e.currentTarget.dataset.index
})
}
.demo-scroll-nav {
height: 80rpx;
}
.nav-wrapper {
height: 100%;
white-space: nowrap;
}
.nav-wrapper text {
display: inline-block;
padding: 0 20px;
height: 100%;
line-height: 80rpx;
}
.nav-wrapper text.active {
color: #ff4400;
}
效果如下:
第三种用法:快速定位联系人
这种用法我们在生活中经常见到,比如手机中联系人的界面,有的选择地址或者国家页面都有类似功能。主要用到了scroll-view中的scroll-into-view属性,类似网页中锚点的功能。例子如下:
<scroll-view scroll-y="true" class="demo-scroll-filter" scroll-into-view="{{toView}}">
<view id="block0">
<view>A</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
</view>
<view id="block1">
<view>B</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
</view>
<view id="block2">
<view>C</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
</view>
<view id="block3">
<view>D</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
</view>
</scroll-view>
<view class="filter-nav">
<view bindtap="toViewId" data-index="0">A</view>
<view bindtap="toViewId" data-index="1">B</view>
<view bindtap="toViewId" data-index="2">C</view>
<view bindtap="toViewId" data-index="3">D</view>
</view>
Page({
data: {
toView:'block0'
},
toViewId(e){
this.setData({
toView:'block'+e.currentTarget.dataset.index
})
},
})
.demo-scroll-filter {
height: 100vh;
}
.filter-nav {
position: fixed;
right: 0;
top: 20rpx;
}
.filter-nav view {
padding: 40rpx;
background: #ff4400;
margin-top: 20rpx;
}
效果如下:
第四种用法:结合第二和第三种用法
这种用就是点击顶部导航,下面的页面中内容就滚动到相应的地方去。废话不说了,直接上代码:
<scroll-view scroll-x="true" class="demo-scroll-nav">
<view class="nav-wrapper">
<text class="{{navIndex == index ? 'active':''}}" wx:for="{{navArr}}" wx:key="unique" bindtap="navChange" data-index="{{index}}">{{item}}</text>
</view>
</scroll-view>
<scroll-view scroll-y="true" class="demo-scroll-filter" scroll-into-view="{{toView}}">
<view id="block{{index}}" wx:for="{{navArr}}" wx:key="unique">
<view>{{index}}</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
<view>阿里</view>
<view>阿猫</view>
<view>阿狗</view>
</view>
</scroll-view>
Page({
data: {
navArr:['指南','框架','组件','API','服务端','工具','云开发','扩展能力','更新日志'],
navIndex:0,
toView:'block0'
},
navChange(e){
this.setData({
navIndex:e.currentTarget.dataset.index,
toView:'block'+e.currentTarget.dataset.index
})
},
})
.demo-scroll-nav {
height: 80rpx;
}
.nav-wrapper {
height: 100%;
white-space: nowrap;
}
.nav-wrapper text {
display: inline-block;
padding: 0 20px;
height: 100%;
line-height: 80rpx;
}
.nav-wrapper text.active {
color: #ff4400;
}
.demo-scroll-filter {
height: calc( 100vh - 80rpx );
}
效果如下:
第五种用法:左右联动
这种用法多用于外卖,点餐以及商城项目中。效果如下:
这种用法难点在于如何滚动右边联动左边的。上代码:
<view class="main">
<view class="scroll-nav">
<view class="{{activeIndex == 0 ? 'active':''}}" bindtap="titleChange" data-index="0">1</view>
<view class="{{activeIndex == 1 ? 'active':''}}" bindtap="titleChange" data-index="1">2</view>
<view class="{{activeIndex == 2 ? 'active':''}}" bindtap="titleChange" data-index="2">3</view>
<view class="{{activeIndex == 3 ? 'active':''}}" bindtap="titleChange" data-index="3">4</view>
<view class="{{activeIndex == 4 ? 'active':''}}" bindtap="titleChange" data-index="4">5</view>
</view>
<view class="scroll-content">
<scroll-view scroll-y="true" style="height:100%" scroll-into-view="{{toView}}" scroll-with-animation="ture" bindscroll="scroll">
<view class="content-item" id="content0">1</view>
<view class="content-item" id="content1">2</view>
<view class="content-item" id="content2">3</view>
<view class="content-item" id="content3">4</view>
<view class="content-item" id="content4">5</view>
</scroll-view>
</view>
</view>
let distance = 0
Page({
data: {
activeIndex:0,
heightArr:[],
toView:'content0'
},
onLoad(){
let query = wx.createSelectorQuery(),self = this
query.selectAll('.content-item').boundingClientRect((rect)=> {
rect.forEach(ele => {
self.calculateHeight(ele.height)
})
}).exec();
},
titleChange(e){
this.setData({
activeIndex:e.currentTarget.dataset.index,
toView: 'content'+e.currentTarget.dataset.index
})
},
scroll(e){
if (this.data.heightArr.length == 0) {
return
}
let scrollTop = e.detail.scrollTop
let current = this.data.activeIndex
if (scrollTop >= this.distance) { //页面向上滑动
//如果右侧当前可视区域最底部到顶部的距离 超过 当前列表选中项距顶部的高度(且没有下标越界),则更新左侧选中项
if (current + 1 < this.data.heightArr.length && scrollTop >= this.data.heightArr[current]) {
this.setData({
activeIndex: current + 1
})
}
} else { //页面向下滑动
//如果右侧当前可视区域最底部到顶部的距离 小于 当前列表选中的项距顶部的高度,则更新左侧选中项
if (current - 1 >= 0 && scrollTop < this.data.heightArr[current - 1]) {
this.setData({
activeIndex: current - 1
})
}
}
//更新到顶部的距离
this.distance = scrollTop
},
// 计算滚动的区间
calculateHeight(height) {
if(!this.data.heightArr.length) {
this.data.heightArr.push(height)
}else {
this.data.heightArr.forEach(ele => {
height += ele
})
this.data.heightArr.push(height);
}
}
})
.main{
height: 100vh;
display: flex;
}
.scroll-nav{
width: 20%;
}
.scroll-nav view{
text-align: center;
padding: 20rpx 0;
}
.scroll-nav view.active{
background: #ff4400;
}
.scroll-content{
flex: 1;
}
.content-item{
height: 600rpx;
}
上面的例子中左边的导航这里是直接用了view,如果这里内容很多也可以使用scroll-view实现,这个就交给大家自己去实现了,我这里只是抛砖引玉哦。
总结
scroll-vew的用法还有很多,目前自己的实际项目中只用这几种方法,如果大家有更多方法,欢迎下面留言探讨哦。