小程序实现下拉二楼,Coolui Scroll v3.2.3 新增下拉刷新二楼组件

1,260 阅读5分钟

前言

前些日子我收到了一个邮件,内容是这个样子的:

随即我就打开了他所说的麦当劳小程序,这不就是下拉二楼的效果么。。。复不复杂先不说,这不妥妥的挑衅么~ 好像我写不出来似的。有求必应,必须安排。何况我也有计划加这个功能。

尝试一:

说干就干,先在社区搜搜看看有没有人搞过这个。不过只搜到了下面这个帖子:  心说我都写小程序了还要自己写结构写动画么,应该不用吧~,而且我的组件库是基于scroll-view封装的。里面新提供了一些属性和方法还挺不错的。比如:

  1. ScrollViewContext.scrollTo(Object object) 这个方法不是可以设置滚动到指定位置还有动画么
  2. scrollEnabled 这个设置不是能控制scroll-view什么时候开始滚动么

然后在scroll-view里设置两个一屏高度的view。然后将scroll-view默认先滚动上去一屏。然后下拉的时候在拉下来,是这个思路。然后就开始写起来。

经过努力搞定了。而且在我的三星手机上效果还不错~ 然后我就拿着我的demo开开心心的去找我的朋友(测试小白鼠),用他高贵的苹果体验一下。等他发过来录屏的视频我傻眼了。。。这怎么在ios下往下拖拽没反应?首先我想到了scrollEnabled,我在touchstart的时候开启,touchend的时候设置关闭。是不是他的问题?注释掉之后果然好了。。。能拖动了,但是这往下滑二楼没有自动往下滚啊。这。。。scrollTo也不好使。看一圈文档确定我写的没问题,enhanced啥的我都开启了。没辙文档也不能全信,安卓和开发者工具好使,ios真机不行~

尝试二:

既然科技不行,那就上狠活被~ 新的渲染引擎Skyline看着不错。而且demo里手势协商那个页面不就是我要的效果么。。。改改就能实现了。这些个手势组件,动画方法想想都激动。 不过凡是留个心眼~我先用ios试试,万一不行呢。。。朋友的ios15.6.1运行官方示例没问题。我掏出我的iphone 6 ios12,小程序正常,点开Skyline的页面直接闪退了。。。果断放弃了

最后的实现:

算了还是踏踏实实写动画吧~ 还是那个思路一个view(wapper) 里套两个一屏高度view(floor、page)。往下拖拽的时候设置view的translateY 移动。利用小程序的界面的animation动画会比自己写的css效果流畅一些。

  1. 先设置外层的wapper默认移动上去一屏高度。
  2. touchmove计算手拖动的距离, 实时改写translateY
  3. 松手时判断。当前移动的距离,如果小于屏幕的六分之一则自动回弹,如果大于六分之一小于三分之一,则页面移动到六分之一的位置开启正在刷新状态。如果大于三分之一,直接移动一屏距离将二楼展现出来。

过程写差不多了,而且也提供了插槽和一些搭配的refresh组件。 这还不够~

我又打开了手机里的一些常见的app去看他们的效果,大受启发~ 我发现有的二楼是从中间展开的,有的是从顶部展开的,有的还带有缩放的效果。思考之后也加了进去。。

1. 基础使用

搭配 second-floor-refresh 组件实现文字提示,同时也提供了插槽位置支持您自定义,自定义 refresh 组件请参考 second-floor-refresh 内部的写法 setText 是关键方法

<second-floor
  bind:refresh="onRefresh"
  bind:secondShow="onSecondShow"
  bind:secondBack="onSecondBack"
  model:threshold="{{val}}"
  class="my-second-floor"
>
  <view slot="second-floor"> 二楼区域 </view>
  <!-- 刷新组件 -->
  <second-floor-refresh slot="second-floor-refresh"></second-floor-refresh>
  <!-- 刷新组件 -->
  <view>页面主内容</view>
</second-floor>
Page({
  data: {
    val: 0, // 拖拽的进度值
  },
  onRefresh() {
    // 下拉刷新时执行
  },
  onSecondShow() {
    // 下拉二楼展开之后执行
  },
  onSecondBack() {
    // 下拉二楼关闭之后执行
  },
});

2. 可搭配 page-container

很多 app 的下拉二楼效果是下拉之后打开一个新页,搭配 page-container, 在 onSecondShow 方法中控制 page-container 的 show 可以实现,然后利用组件的 back 事件进行关闭

示例

<second-floor
  bind:refresh="onRefresh"
  bind:secondShow="onSecondShow"
  bind:secondBack="onSecondBack"
  model:threshold="{{val}}"
  class="my-second-floor"
>
  <view slot="second-floor"> 二楼区域 </view>
  <!-- 刷新组件 -->
  <second-floor-refresh slot="second-floor-refresh"></second-floor-refresh>
  <!-- 刷新组件 -->
  <view>页面主内容</view>
</second-floor>

<page-container
  show="{{show}}"
  round="{{round}}"
  overlay="{{overlay}}"
  duration="{{duration}}"
  position="{{position}}"
  close-on-slide-down="{{false}}"
  bindbeforeenter="onBeforeEnter"
  bindenter="onEnter"
  bindafterenter="onAfterEnter"
  bindbeforeleave="onBeforeLeave"
  bindleave="onLeave"
  bindafterleave="onAfterLeave"
  bindclickoverlay="onClickOverlay"
  custom-style="{{customStyle}}"
  overlay-style="{{overlayStyle}}"
>
  <view class="detail-page">
    <button type="primary" bindtap="exit">退出</button>
  </view>
</page-container>
Page({
  data: {
    val: 0, // 拖拽的进度值
    show: false,
    duration: 300,
    position: "right",
    round: false,
    overlay: true,
    customStyle: "",
    overlayStyle: "",
  },
  onRefresh() {
    // 下拉刷新时执行
  },
  onSecondShow() {
    // 下拉二楼展开之后执行
    setTimeout(() => {
      this.setData({
        show: true,
      });
    }, 500);
  },
  onSecondBack() {
    // 下拉二楼关闭之后执行
  },
  exit() {
    const secondFloor = this.selectComponent(".my-second-floor");
    secondFloor.back().then(() => {
      this.setData({ show: false });
    });
  },
});

3. 可设置下拉二楼的位置

可设置下拉二楼的位置 top、center、bottom。即展开的时候先展示的是二楼的哪个部位

示例 示例 示例

<!-- top -->
<second-floor top></second-floor>
<!-- center -->
<second-floor center></second-floor>
<!-- bottom -->
<second-floor bottom></second-floor>

4. 可设置下拉二楼是否开启缩放动画

就如同微信首页下拉出来小程序列表一样,二楼展开会有一个缩放的效果

示例 示例 示例

<!-- top scale -->
<second-floor top scale></second-floor>
<!-- center scale-->
<second-floor center scale></second-floor>
<!-- bottom scale-->
<second-floor bottom scale></second-floor>

second-floor 配置

参数说明类型默认值版本
top二楼初始位置Booleanfalse3.2.3
center二楼初始位置Booleanfalse3.2.3
bottom二楼初始位置Booleantrue3.2.3
scale二楼是否开启缩放动画Booleanfalse3.2.3

插槽

名称说明可用组件
second-floor二楼插槽区域-
second-floor-refresh下拉刷新插槽位置second-floor-refresh

methods 方法

名称用法说明版本
settriggered先获取组件实例:
const secondFloor = this.selectComponent('.my-second-floor');, 然后调用方法:
secondFloor.settriggered()
关闭刷新的方法,在 onRefresh 中,数据刷新之后执行,返回 Promise3.2.3
back先获取组件实例:
const secondFloor = this.selectComponent('.my-second-floor');, 然后调用方法:
secondFloor.back()
关闭二楼的方法,会触发 onSecondBack, 返回 Promise3.2.3

events 事件

名称用法说明版本
refreshbind:refresh刷新时执行,可执行请求数据,然后执行 settriggered 关闭刷新3.2.3
secondShowbind:secondShow二楼打开之后执行3.2.3
secondBackbind:secondBack二楼关闭之后执行3.2.3

second-floor-refresh 配置

参数说明类型默认值版本
refreshConfigsecond-floor-refresh 组件的设置,详见refreshConfigObject{ downText: "下拉刷新", loadingText: "正在加载", backText: "返回首页", tipText: "松开刷新", moreText: "继续下拉有惊喜~", color: "#ffffff" }3.2.3

refreshConfig

参数说明类型默认值版本
downText开始下拉时的文字Booleanfalse3.2.3
loadingText正在加载时的文字Booleanfalse3.2.3
backText二楼加载成功之后返回按钮的文字Booleanfalse3.2.3
tipText松开刷新时的提示文字Booleanfalse3.2.3
moreText继续下拉的提示文字Booleanfalse3.2.3
color文字颜色Booleanfalse3.2.3

示例 demo

请微信扫码打开小程序查看

示例

详细文档

gitee文档入口 github文档入口