scroll flip page

🎁A super easy to use infinite scroll component.(Vue component)

100
13
Vue

scroll-flip-page

A super easy to use infinite scroll component.(Vue component)

Intro

scroll-flip-page 是一个 Vue 组件,它让你轻松的就能够实现无限滚动加载(翻页)的功能,而不需要考虑更多。

Installation

该组件封装自开源框架 finger-moversimulation-scroll-y 插件,故你需要安装之:

npm install --save finger-mover simulation-scroll-y scroll-flip-page

Why?

在做移动设备上的应用时,我们经常会开发无限滚动加载更多、下拉刷新的功能,也就是移动端的翻页,那么下面我们就看看实现这样一个功能你需要考虑什么:

假设起始页码是 1,每页数据 20 条:

  • 一、加载第一页数据

加载第一页数据的时候分三种情况,①:一条数据都没有;②:数据少于 20 条,即不足一页;③、数据满足一页

  • 二、第一页数据加载完之后,向上滑动加载更多数据

第一页数据加载完成后,根据三种不同的情况,向上滑动加载更多的行为也不同:

④:对于 ①,由于一条数据都没有,此时可能会展示无数据页面,所以不存在加载更多的情况

⑤:对于 ②,有数据,但不足一页,此时用户可以向上滑动加载更多,那么问题来了,加载更多的时候应该加载第一页数据还是第二页数据?你可能会觉得第一页数据已经不足一页了,还有必要让用户上滑加载更多吗?有肯定是有,不过你也可以选择不再加载更多数据,但是更好的行为是仍然加载第一页数据,而不是第二页,因为虽然目前第一页数据不足,但你并不能保证下一秒钟第一页数据还不足,很可能在你打个喷嚏的时候,数据库中的数据就多了几十条。所以此时页码不能 +1

⑥:对于 ③,数据满足一页,那么理所当然的页码要 +1,继续请求第二页数据

  • 三、加载第二页数据

⑦:假设我们来到了情况 ⑥,此时第一页数据满足一页,我们需要页码 +1 请求第二页数据,第二页数据的请求结果同样有三种情况:⑧:一条数据都没有;⑨:数据少于 20 条,即不足一页;⑩、数据满足一页

  • 四、第二页数据加载完之后,向上滑动加载更多数据

对于 ⑧:此时第二页数据为空,所以页码要 -1,以允许下次继续请求该页数据。

对于 ⑨:此时第二页有数据,但是不足一页,那么此时与情况 ⑤ 类似,即下一次加载更多的时候仍然请求第二页数据,所以此时页码要 -1,以保证下一次仍然请求第二页数据并替换之前的第二页数据(不替换掉岂不是会有重复数据)

对于 ⑩:此时第二页数据满足一页,这时什么都不用做了,下一次加载更多时候页码 +1 请求第三页数据。

  • 五、下拉刷新需要重置页码

除了以上四点需要考虑,下拉刷新的时候,你需要把页码重置为起始页码。

  • 六、更新滚动区域

无论是下拉刷新还是加载更多,亦或是其他导致列表数据变化,你都调用滚动插件的重新计算滚动尺寸的方法。

Features

Demo

该项目提供一个获取 Vue 项目 contributors 列表的 Demo:

如何运行该 Demo?使用简单强大的 poi,也强烈推荐你说用。

git clone 该项目
npm install -g poi
npm run dev

即将会有一个针对该 Demo 的教程,敬请期待…

Usage

import ScrollFlipPage from 'scroll-flip-page'

// register globally
Vue.component(ScrollFlipPage)

// or locally
export default {
  components: {
    ScrollFlipPage
  }
}

v-model

使用 v-model 绑定列表数据:

<scroll-flip-page v-model="dataList">
  <div v-for="item of dataList">{{item.name}}</div>
</scroll-flip-page>

Props

name type required default description
scroll-bar Boolean NO true 是否显示滚动条
unidirectional Boolean NO false 是否单向滑动,详情查看unidirectional
bounce Boolean NO true 是否开启边界弹性
pullDown Object NO 查看pullDown 下拉刷新配置
loadMore Object NO 查看loadMore 无限滚动配置
fetch Function YES scroll-flip-page 将使用该函数获取数据,该函数需要返回一个 Promise
dataField String YES 告诉 scroll-flip-page 使用数据的哪一个字段作为列表数据
check Function YES scroll-flip-page 用来判断获取数据是否成功
initial Boolean NO true 是否初始化渲染数据
pageSize Number NO 20 每页数据尺寸,scroll-flip-page 将用它来判断数据是否满足一页
startPage Number NO 0 第一页的页码,默认从 0 开始
interceptor Function NO 用来预处理数据,在列表数据真正被赋值到通过 v-model 绑定的字段之前被调用,该函数必须返回处理后的列表数据,并且该数据将会被赋值给通过 v-model 绑定的字段

Slots

name description
pulldown 下拉动作(如下拉刷新)自定义的DOM内容插槽
loadmore 无限滚动自定义DOM内容插槽
<scroll-flip-page
  v-model="contributors"
  :fetch="fetchData"
  data-field="body"
  :start-page="1"
  :check="res => res.ok"
>
  <!-- DOM for pulling down the refresh -->
  <div :class="$style.pullDownDom" slot="pulldown">下拉刷新</div>

  
  <!-- For infinite scrolling of DOM -->
  <div :class="$style.loadMoreDom" slot="loadmore" slot-scope="{ isNoData }">
    <span v-show="isNoData">没有更多数据</span>
    <span v-else>加载中...</span>
  </div>
</scroll-flip-page>

scroll-flip-page 组件并没有提供内置的 pulldownloadmore DOM结构以及布局,原因是一直以来大家在开发这块相关的内容时,基本都会有自己自定义的下拉刷新和无限滚动的样式。

比如有的产品要求下拉刷新的DOM结构要跟随可滚动元素一起动,有的产品则设计为下拉刷新DOM隐藏在可滚动元素后面,当拖动下拉时会展示下拉刷新DOM,而不是与可滚动元素一起滚动,出于此,组件的思想是:你可以完全自定义你想要的刷新DOM的模式以及样式。

如果你需要一些思路可以查看:pulldown 的示例部分 以及 loadmore 的示例部分

Events

运动相关事件
name description parameters
on-touchstart touchstart 事件 (isMotion):当 touchstart 事件触发时,元素是否在滚动
on-touchmove touchmove 事件 (currentY):滚动元素当前的位置
on-touchend touchend 事件 (isMotion):当 touchend 事件触发时,元素是否在滚动
on-transmove 元素惯性滚动时持续触发 (currentY):滚动元素当前的位置
on-transmove-end 元素滚性滚动结束时触发 (currentY):滚动元素当前的位置
on-motion-stop 元素运动停止时触发(on-transmove-endon-motion-stop 的子集) (currentY):当滚动元素运动停止时触发
业务逻辑相关事件
name description parameters
on-nothing 当页码为起始页码且没有数据时触发,即:第一页就没有数据
on-having 无论何时,只要请求有数据返回就会触发
on-backend-error check props 检验为假时触发 (res):请求返回的数据对象
on-network-error 网络出错时触发,比如无网状态等,注意:不排除是代码报错引起的原因所引起 (err):捕获到的错误信息
on-pull-refresh 达到下拉刷新临界点后触发 pullDown: { onActive: function () {} } 的封装
on-load-more 达到加载更多临界点后触发 loadMore: { onLoadMore: function () {} } 的封装

Methods

通过给 <scroll-flip-page></scroll-flip-page> 组件定义 ref 属性:

<scroll-flip-page ref="sfp"></scroll-flip-page>

可以在父组件中方法该组件,从而调用组件的方法:

mounted () {
  const sfp = this.$refs.sfp
  sfp.fetchData() // 如果 initial Props 设置为 false,那么可以通过该方法手动获取数据
  sfp.scrollTo(-300, 1000) // 手动滚动元素
}

可调用的组件方法以及方法的调用方式请参考:simulation-scroll-y 的实例方法

License

MIT

Copyright © 2017, HcySunYang