美文网首页
BetterScroll 2.0 发布:精益求精,与你同行(转载

BetterScroll 2.0 发布:精益求精,与你同行(转载

作者: lessonSam | 来源:发表于2020-09-03 18:24 被阅读0次

    BetterScroll 2.0 发布:精益求精,与你同行

    BetterScroll v1 版本发布至今已经两年多,这期间 BetterScroll 无论是在我们公司内部的业务以及社区内,经受住了大量的场景考验,同时也新增了不少特性。无论是我们内部开源组件库的 cube-ui,还是社区内的 mpxtarovue-better-scroll 的组件底层也都是依赖 BetterScroll 实现。为什么大家都愿意尝试 BetterScroll,其一是良好的事件系统,其二是优秀的滚动体验,其三是涵盖了较多的移动端常见滚动场景。

    v1 的成绩

    • 发布 30 多个版本
    • 累计处理 600 多个 issues
    • npm 月下载量 5 万
    • 累计 star 12600 多个
    • github 4 万多个 repos 依赖

    BetterScroll 是受前辈 iscroll 的启发而来,目前 star 数量也已经超过前辈。iscroll 在 2017 年已经停止了维护,但我们依然在维护着 BetterScroll,并且从大量的业务场景以及社区的声音中得到了启发和沉淀。

    为什么做 v2

    做 v2 版本的初衷源于社区的一个需求:

    • BetterScroll 能不能支持按需加载?

    这个问题提的非常好,也一针见血地指出 v1 版本的缺陷,因为对于 v1 版本,所有的 feature 都是通过 options 选项并且通过一个 BScroll 类以及扩展原型方法来实现的。

    先来看看 v1 的部分代码:

    // 节选 BetterScroll v1 部分源码
    BScroll.prototype._init = function (options) {
      this._iniExtFeatures()
    }
    
    BScroll.prototype._iniExtFeatures = function (options) {
      if (this.options.snap) {
        this._initSnap()
      }
      if (this.options.scrollbar) {
        this._initScrollbar()
      }
      if (this.options.wheel) {
        this._initWheel()
      }
      // ... 省略后续代码
    }
    复制代码
    

    所以针对于按需加载问题的答案当然是不能

    从上述代码来看,v1 版本无法做到按需加载,并且随着功能扩展,用户被迫加载许多冗余代码,因为对于用户来说,绝对多数场景只需要其中的几个 feature。

    当然我们也不能说 v1 版本的实现不好,这恰恰是一个类库的演化史,从简单的场景到支持多功能场景,最后到分包并且实现可插拔,BetterScroll 2.0 也因此得以诞生。

    v2 做了什么

    BetterScroll 2.0 采用了插件化的架构设计。CoreScroll 作为最小的滚动单元,暴露了丰富的事件以及钩子,其余的功能都由不同的插件来扩展,这样会让 BetterScroll 更加的灵活,也能解耦不同的场景。下面是整体的架构图:

    [图片上传中...(image-7c8db6-1599128603904-13)]

    <figcaption style="display: block; text-align: center; font-size: 1rem; line-height: 1.6; color: rgb(144, 144, 144); margin-top: 2px;"></figcaption>

    项目采用的是 monorepos 的组织方式,每个插件都是一个 npm package,代码都是使用 TypeScript 来编写,同时我们内部也是极大的利用了 TypeScript 的优点,这个会在后面讲到。因此,对于 v2 实现一个基本的滚动需求,代码如下:

    import BScroll from '@better-scroll/core'
    
    const bs = new BScroll('.wrapper', {})
    复制代码
    

    除了 package 的引入,其余与 v1 的使用方式一模一样。

    下面逐一介绍一下各种插件的功能。

    插件

    1.x 的 feature 都将以 plugin 的形式实现,这种插件化的设计不仅有益于实现按需加载,也非常适合自身库的后期迭代升级,减少对主逻辑的侵入。插件的使用方式都大同小异。分为引入——注册——配置 options 三个步骤。下面以 pulldown 插件为例。

    import BScroll from '@better-scroll/core'
    import PullDown from '@better-scroll/pull-down'
    
    BScroll.use(PullDown)
    
    // pullDownRefresh 可以配置为 true
    const bs = new BScroll('.wrapper', {
      pullDownRefresh: true
    })
    
    // or pullDownRefresh 也可以配置为选项对象
    const bs = new BScroll('.wrapper', {
      pullDownRefresh: {
        threshold: 50,
        stop: 30
      }
    })
    复制代码
    

    下面一起看下在 v2 版本中所有的插件集合:

    • pulldown

      [图片上传中...(image-2ab70-1599128603903-12)]

      实现仿 App 下拉刷新效果。

    • pullup

      [图片上传中...(image-49e25c-1599128603903-11)]

      实现仿 App 上拉加载效果。

    • movable

      [图片上传中...(image-3b8317-1599128603903-10)]

      仿微信小程序 movable-view。

      新增于 v2 版本,来源于社区对我们提的需求
      复制代码
      
    • slide

      [图片上传中...(image-46d02d-1599128603903-9)]

      轮播焦点图。

      v2 对 slide 底层进行重构:
        1\. 支持 autoplay 配置项;
        2\. 友好响应 resize 事件;
        3\. 支持在 loop 模式下动态添加 slidePage。
        4\. 添加 `slideWillChange` 事件,支持焦点实时更改
      注意:实例化 slide 的 options 配置项不再是 `snap`,而是 `slide`
      复制代码
      
    • zoom

      [图片上传中...(image-99b164-1599128603903-8)]

      图片放大缩小。

      v2 对 zoom 进行重构:
        1\. 支持以某一个原点进行缩放;
        2\. 精确派发 beforeZoomStart、zoomStart、zooming、zoomEnd 等事件
           并且暴露当前 scale 供用户消费。
      复制代码
      
    • picker

      [图片上传中...(image-59d4fa-1599128603903-7)]

      仿 iOS picker 组件。

    • scrollbar

      [图片上传中...(image-cc795e-1599128603903-6)]

      定制化滚动条。

    • mouse-wheel

      [图片上传中...(image-abf83e-1599128603903-5)]

      通过鼠标滚轮进行交互。

      v2 对 mouse-wheel 进行重构:
        1\. 搭配 picker;
        2\. 搭配 pulldown;
        3\. 搭配 pullup;
      复制代码
      
    • infinity

      [图片上传中...(image-6b8e55-1599128603903-4)]

      实现列表的无限滚动加载,对于大量数据渲染有显著效果。

    • nested-scroll

      [图片上传中...(image-aae253-1599128603903-3)]

      协调双层 BetterScroll 嵌套滚动行为。

      于 v2 版本新增,解决横向套横向,竖向套竖向的双层嵌套滚动的协调问题。
      复制代码
      

    从上述插件来看,得益于插件化的架构设计,BetterScroll 可以基于很多种滚动的场景延伸出更多的插件,由于插件是在不同的 npm 包中,对于用户来说,再也没有被迫加载冗余代码的心智负担

    TypeScript

    为了更友好的开发体验,我们选择了 TypeScript,TypeScript 作为冉冉上升的新星,自然存在很多的优点,当然对于 Javascript 动态语言以及 Javascript OOP 编程中,我们在 BetterScroll 2.0 的重构当中的 TypeScript 使用可谓是一波三折,不过我们依旧排除了万难,在我们这种以 class 类作为架构设计主体的库里面,充分的使用了 TypeScript 优点,我们以 pulldown 插件为例子。

    • 不加载插件

      [图片上传中...(image-712088-1599128603903-2)]

      不加载插件,传入 options 时也没有 pullDownRefresh 的提示,bs 实例上没有 pulldown 插件注入的 autoPullDownRefresh 方法的提示。

    • 加载插件

      [图片上传中...(image-19f6cc-1599128603903-1)]

      [图片上传中...(image-bf665-1599128603903-0)]

      加载 pulldown 插件,有对应插件的 options 提示,bs 实例也有对应 autoPullDownRefresh 方法的提示,这就是 TypeScript 的魅力。

    这种提示不管是对于用户还是我们自己内部的开发者,都很爽。因为爽,才会有更多的人来尝试 BetterScroll。

    文档

    v1 版本的文档存在很多不足,也收到了社区很多的反馈,在汲取了社区的建议之后,我们基于 VuePress 拓展了 markdown 的能力,支持示例、代码、二维码、复制等功能于一体,方便大家能够在 PC 或者手机都能方便预览、调试代码。当然,大家如果想要调试 examples,可以 clone repo,直接执行 yarn vue:dev 即可。

    [图片上传中...(image-1f492-1599128603905-14)]

    而且为了降低大家在使用 BetterScroll 的时候遇到一些 “疑难杂症” 的成本,我们还开辟了一个 FAQ 版本,大家也可以把自己遇到的经典问题通过 PR 的方式汇集在这里。

    与你同行

    以上十多个插件,可能也只是 BetterScroll 的冰山一角,可能对于你的场景,可以抽象出新的 BetterScroll 插件,因此非常欢迎你一起参与到 BetterScroll 生态的共建当中,抽象出更多的插件。我们已经为大家准备了如何写一个 BetterScroll 插件的教程。完整的 github repo 在这,你也可以通过预览地址看看效果。

    当然,不只是插件,包括测试、示例、文档,只要是好的建议,我们都可以一起来完善 BetterScroll 生态。

    总结规划

    BetterScroll 仍然是一个成长中的项目,在这个过程中,我们也在不断的思考,不断的巩固 BetterScroll,同时也非常欢迎社区的同学一起参与。后续我们会朝着以下方向继续努力:

    1. 单测、功能测试完善
    2. 优化示例代码和文档,降低上手难度
    3. 现有插件优化以及更多的插件支持,如 keyBindings,全屏场景转换等等
    4. 提供 react 版本示例

    如果你对 BetterScroll 感兴趣或者曾经受益于 BetterScroll,欢迎给我们一个 Star,github.com/ustbhuangyi…

    最后附上文档、示例,欢迎体验&使用:

    相关文章

      网友评论

          本文标题:BetterScroll 2.0 发布:精益求精,与你同行(转载

          本文链接:https://www.haomeiwen.com/subject/gduosktx.html