突然耳朵聋是什么原因| 少尉是什么级别| 龋齿是什么原因造成的| 吃什么补蛋白| 印度为什么用手吃饭| 国花是什么| 什么是蜘蛛痣图片| loreal是什么品牌| 吃皮是什么意思| 热伤风吃什么药| 翩翩起舞是什么意思| 肠炎吃什么药好得快| 星月菩提是什么材质| 林冲到底属什么生肖的| 早孕试纸什么时候测最准确| 为什么会咳嗽| 耵聍是什么东西| 审计署是什么级别| ct 是什么| 副部长是什么级别| 复检是什么意思| 月经十多天不干净是什么原因| 一什么白菜| 脚软没力气是什么原因引起的| 孕妇血压低吃什么能补上来| 脂蛋白是什么| 为什么会梦到自己怀孕| 肠胀气是什么原因引起的怎么解决| 下丘脑分泌什么激素| 梦见自己升职了是什么预兆| 同好是什么意思| 95年属什么| 心率过缓吃什么药| 毕业送老师什么礼物好| 腰疼吃点什么药| 送产妇什么礼物最合适| 威士忌什么味道| 祛痣挂什么科| 上大号出血是什么原因| 背疼是什么原因| 吃什么补心| 什么的贝壳| studio什么牌子| 胃下垂吃什么药最好| 落马是什么意思| 红月亮是什么兆头| 小排畸什么时候做| 梦见栽树是什么意思| 哆啦a梦为什么没有耳朵| 梦到丢了一只鞋是什么意思| 如是我闻是什么意思| 国家为什么要扫黄| 胃不舒服恶心想吐吃什么药| 落井下石什么意思| 牙疼吃什么药| mac版本是什么意思| 四个金念什么| 薄荷叶晒干后能干什么| 银灰色五行属什么| 尿起泡沫是什么原因| 心房扑动是什么意思| 尿蛋白是什么病| 吐气如兰是什么意思| dha有什么作用与功效| 滞后是什么意思| 目前是什么意思| 检查肝挂什么科| 为什么要长智齿| 乳杆菌是什么| omo是什么意思| 七月份适合种什么蔬菜| 肠息肉是什么原因引起的| 柚子不能和什么一起吃| 成人自考本科需要什么条件| 高密度脂蛋白胆固醇偏低是什么原因| 痘痘挤出来的白色东西是什么| 诺氟沙星胶囊治什么病| 来月经可以吃什么水果好| 什么叫低钾血症| 成都人民公园有什么好玩的| 西柚是什么季节的水果| 喝什么去湿气| 大佬什么意思| 充电宝什么品牌好| 后羿属什么生肖| 火鸡是什么鸡| pt指什么| 什么是种草| 白细胞低是什么原因造成的| 例假是什么意思| 中药不能和什么一起吃| 烟草是什么植物| 面基是什么意思啊| 防中暑喝什么水| 什么属相不能挂山水画| 肠息肉是什么原因引起的| 什么是桥本病| 世界上牙齿最多的动物是什么| 鞘膜积液是什么病| 紫菜不能和什么一起吃| 结晶是什么| 喝红茶有什么效果| 保家卫国是什么生肖| 蹦蹦跳跳是什么生肖| 子宫外怀孕有什么症状| 红颜什么意思| 大麦茶是什么做的| 春季感冒吃什么药| 抑郁看病看什么科| spiderman是什么意思| 自慰用什么| 癞皮狗是什么意思| 科学是什么| 毛囊炎是什么样子| 早泄要吃什么药| 尿检白细胞弱阳性是什么意思| 规律宫缩是什么感觉| 甲鱼吃什么| 什么叫洗钱| 肉包子打狗的歇后语是什么| 口臭口干口苦是什么原因| 乔迁对联什么时候贴| 白茶属于什么茶| 瓜子脸配什么发型好看| 葡式蛋挞为什么叫葡式| 男人吃鸽子有什么好处| 睾酮低有什么影响| d二聚体高是什么原因| 梦见蒸馒头是什么意思| 带状疱疹挂什么科室| 阑尾炎什么症状表现| 父亲的弟弟叫什么| 打边炉是什么| 吃生姜对身体有什么好处和坏处| 李嘉诚属什么生肖| 工作单位是什么| 鸡枞是什么| 荨麻疹为什么晚上起| panerai是什么牌子| 三级护理是什么意思| 表姐的孩子叫我什么| 吃什么可以增加黄体酮| 电表走的快是什么原因| 什么是阳光抑郁症| 单飞是什么意思| 小孩反复发烧是什么原因| 山今读什么| 阴阳和合是什么意思| 尖锐湿疣用什么药| 手心出汗什么原因| 代肝是什么意思| 知性女性是什么意思| rov是什么意思| 家里养什么花最好| 夜尿频多是什么原因| 左大腿外侧麻木是什么原因| 反流性食管炎吃什么药最好| 晚上没有睡意什么原因| 44岁月经量少是什么原因| 类风湿关节炎吃什么好| 青茶是什么茶| 宫腔内异常回声是什么意思| bv是什么品牌| 昆仑雪菊有什么功效| 什么是气胸| 真实的印度是什么样的| 张钧甯为什么读mi| 脂肪肝是什么引起的| 肉桂是什么| 脸一边大一边小是什么原因| 坐月子吃什么水果好| 槟榔为什么那么贵| 分泌物发黄是什么原因| 什么的苹果| 手串18颗代表什么意思| 龙眼树上的臭虫叫什么| 千山暮雪结局是什么| 程度是什么意思| 什么时候怀孕几率高| 梦见弟弟是什么意思| 甲亢是什么原因| 息肉是什么东西| 乙肝病毒表面抗原阳性是什么意思| 阴阳失调是什么意思| 1007是什么星座| 女生怀孕的前兆是什么| 肾虚吃什么补| dose是什么意思| 什么是心肌缺血| 局座是什么梗| 仙人掌有什么作用| 肺气肿是什么原因导致的| 盆底肌松弛有什么症状| 什么花最香| 血脂高吃什么水果最好| 宫内妊娠是什么意思| 肝脏在什么位置图片| 4月6号是什么星座| 血常规crp是什么意思| 脖子痛挂什么科| 尿细菌计数高是什么原因| 尿胆红素2十是什么意思| 荷兰机场叫什么| 胆囊结石不能吃什么| 农历7月是什么月| 乳果糖什么时候吃效果更佳| 手掌像什么| 为什么做b超要憋尿| 热气是什么意思| 智齿是什么牙| 点了斑不能吃什么| 凶宅是什么意思| neu是什么意思| 做梦梦到鸡是什么意思| 妊娠期是什么意思| 睡不着觉吃什么药效果好| 366红包代表什么意思| 螳螂捕蝉黄雀在后是什么生肖| 内含是什么意思| 瑞士移民需要什么条件| 形同陌路什么意思| 肾结晶是什么意思| 蔬菜有什么| 什么是什么的摇篮| 什么耳朵| 一个月来两次例假是什么原因| 油腻腻的什么| 伸筋草主治什么病| 什么是修辞手法| 焦作有什么大学| 肺炎是什么| 精囊腺囊肿是什么意思| 什么是狐臭| 苏字五行属什么| 人潮汹涌是什么意思| 乙肝病毒是什么| 9.1号是什么星座| 27岁属相是什么生肖| 什么叫滑精| 为什么会感染hpv| 天乙贵人什么意思| 什么症状吃藿香清胃胶囊| 什么食物养胃又治胃病| 大于90度的角是什么角| 唐氏综合症是什么| 平板和ipad有什么区别| 榴莲什么味道| 孩子记忆力差是什么原因| 犹太人属于什么人种| 送产妇什么礼物最合适| 侃侃而谈什么意思| prada是什么品牌| 卵巢保养最好的方法是什么| 28周检查什么项目| 百合花什么时候种植| 血府逐瘀丸治什么病| 紫癜是什么病| 中将相当于什么级别| 单抗主要治疗什么| 三个毛念什么| 珊瑚粉是什么颜色| 人这一生为了什么| 动物园里有什么动物| 生不逢时什么意思| 百度
Skip to content

wechat-miniprogram/recycle-view

Repository files navigation

recycle-view

小程序自定义组件

使用此组件需要依赖小程序基础库 2.2.2 版本,同时依赖开发者工具的 npm 构建。具体详情可查阅官方 npm 文档

背景

? 电商小程序往往需要展示很多商品,当一个页面展示很多的商品信息的时候,会造成小程序页面的卡顿以及白屏。原因有如下几点:

  1. 商品列表数据很大,首次 setData 的时候耗时高
  2. 渲染出来的商品列表 DOM 结构多,每次 setData 都需要创建新的虚拟树、和旧树 diff 操作耗时都比较高
  3. 渲染出来的商品列表 DOM 结构多,占用的内存高,造成页面被系统回收的概率变大。

因此实现长列表组件来解决这些问题。

实现思路

? 核心的思路就是只渲染显示在屏幕的数据,基本实现就是监听 scroll 事件,并且重新计算需要渲染的数据,不需要渲染的数据留一个空的 div 占位元素。

? 假设列表数据有100个 item,知道了滚动的位置,怎么知道哪些 item 必须显示在页面?因为 item 还没渲染出来,不能通过 getComputedStyle 等 DOM 操作得到每个 item 的位置,所以无法知道哪些 item 需要渲染。为了解决这个问题,需要每个 item 固定宽高。item 的宽高的定义见下面的 API 的createRecycleContext()的参数 itemSize 的介绍。

? 滚动过程中,重新渲染数据的同时,需要设置当前数据的前后的 div 占位元素高度,同时是指在同一个渲染周期内。页面渲染是通过 setData 触发的,列表数据和 div 占位高度在2个组件内进行 setData 的,为了把这2个 setData 放在同一个渲染周期,用了一个 hack 方法,所以定义 recycle-view 的 batch 属性固定为batch="{{batchSetRecycleData}}"

? 在滚动过程中,为了避免频繁出现白屏,会多渲染当前屏幕的前后2个屏幕的内容。

包结构

长列表组件由2个自定义组件 recycle-view、recycle-item 和一组 API 组成,对应的代码结构如下

├── miniprogram-recycle-view/
    └── recycle-view 组件
    └── recycle-item 组件
    └── index.js

包结构详细描述如下:

目录/文件 描述
recycle-view 组件 长列表组件
recycle-item 组件 长列表每一项 item 组件
index.js 提供操作长列表数据的API

使用方法

  1. 安装组件
npm install --save miniprogram-recycle-view
  1. 在页面的 json 配置文件中添加 recycle-view 和 recycle-item 自定义组件的配置

    {
      "usingComponents": {
        "recycle-view": "miniprogram-recycle-view/recycle-view",
        "recycle-item": "miniprogram-recycle-view/recycle-item"
      }
    }
  2. WXML 文件中引用 recycle-view

    <recycle-view batch="{{batchSetRecycleData}}" id="recycleId">
      <view slot="before">长列表前面的内容</view>
      <recycle-item wx:for="{{recycleList}}" wx:key="id">
        <view>
            <image style='width:80px;height:80px;float:left;' src="{{item.image_url}}"></image>
          {{item.idx+1}}. {{item.title}}
        </view>
      </recycle-item>
      <view slot="after">长列表后面的内容</view>
    </recycle-view>

    recycle-view 的属性介绍如下:

    字段名 类型 必填 描述
    id String id必须是页面唯一的字符串
    batch Boolean 必须设置为{{batchSetRecycleData}}才能生效
    height Number 设置recycle-view的高度,默认为页面高度
    width Number 设置recycle-view的宽度,默认是页面的宽度
    enable-back-to-top Boolean 默认为false,同scroll-view同名字段
    scroll-top Number 默认为false,同scroll-view同名字段
    scroll-y Number 默认为true,同scroll-view同名字段
    scroll-to-index Number 设置滚动到长列表的项
    placeholder-image String 默认占位背景图片,在渲染不及时的时候显示,不建议使用大图作为占位。建议传入SVG的Base64格式,可使用工具将SVG代码转为Base64格式。支持SVG中设置rpx。
    scroll-with-animation Boolean 默认为false,同scroll-view的同名字段
    lower-threshold Number 默认为false,同scroll-view同名字段
    upper-threshold Number 默认为false,同scroll-view同名字段
    bindscroll 事件 同scroll-view同名字段
    bindscrolltolower 事件 同scroll-view同名字段
    bindscrolltoupper 事件 同scroll-view同名字段

    recycle-view 包含3个 slot,具体介绍如下:

    名称 描述
    before 默认 slot 的前面的非回收区域
    默认 slot 长列表的列表展示区域,recycle-item 必须定义在默认 slot 中
    after 默认 slot 的后面的非回收区域

    ? 长列表的内容实际是在一个 scroll-view 滚动区域里面的,当长列表里面的内容,不止是单独的一个列表的时候,例如我们页面底部都会有一个 copyright 的声明,我们就可以把这部分的内容放在 before 和 after 这2个 slot 里面。

    recycle-item 的介绍如下:

    ? 需要注意的是,recycle-item 中必须定义 wx:for 列表循环,不应该通过 setData 来设置 wx:for 绑定的变量,而是通过createRecycleContext方法创建RecycleContext对象来管理数据,createRecycleContext在 index.js 文件里面定义。建议同时设置 wx:key,以提升列表的渲染性能。

  3. 页面 JS 管理 recycle-view 的数据

    const createRecycleContext = require('miniprogram-recycle-view')
    Page({
        onReady: function() {
            var ctx = createRecycleContext({
              id: 'recycleId',
              dataKey: 'recycleList',
              page: this,
              itemSize: { // 这个参数也可以直接传下面定义的this.itemSizeFunc函数
                width: 162,
                height: 182
              }
            })
            ctx.append(newList)
            // ctx.update(beginIndex, list)
            // ctx.destroy()
        },
        itemSizeFunc: function (item, idx) {
            return {
                width: 162,
                height: 182
            }
        }
    })

    typescript支持,使用如下方式引入

    import * as createRecycleContext from 'miniprogram-recycle-view';

    ? 页面必须通过 Component 构造器定义,页面引入了miniprogram-recycle-view包之后,会在 wx 对象下面新增接口createRecycleContext函数创建RecycleContext对象来管理 recycle-view 定义的的数据,createRecycleContext接收类型为1个 Object 的参数,Object 参数的每一个 key 的介绍如下:

    参数名 类型 描述
    id String 对应 recycle-view 的 id 属性的值
    dataKey String 对应 recycle-item 的 wx:for 属性设置的绑定变量名
    page Page/Component recycle-view 所在的页面或者组件的实例,页面或者组件内可以直接传 this
    itemSize Object/Function 此参数用来生成recycle-item的宽和高,前面提到过,要知道当前需要渲染哪些item,必须知道item的宽高才能进行计算
    Object必须包含{width, height}两个属性,Function的话接收item, index这2个参数,返回一个包含{width, height}的Object
    itemSize如果是函数,函数里面this指向RecycleContext
    如果样式使用了rpx,可以通过transformRpx来转化为px。
    为Object类型的时候,还有另外一种用法,详细情况见下面的itemSize章节的介绍。
    useInPage Boolean 是否整个页面只有recycle-view。Page的定义里面必须至少加空的onPageScroll函数,主要是用在页面级别的长列表,并且需要用到onPullDownRefresh的效果。切必须设置root参数为当前页面对象
    root Page 当前页面对象,可以通过getCurrentPages获取, 当useInPage为true必须提供

    RecycleContext 对象提供的方法有:

    方法 参数 说明
    append list, callback 在当前的长列表数据上追加list数据,callback是渲染完成的回调函数
    splice begin, count, list, callback 插入/删除长列表数据,参数同Array的splice函数,callback是渲染完成的回调函数
    update begin, list, callback 更新长列表的数据,从索引参数begin开始,更新为参数list,参数callback同splice。
    destroy 销毁RecycleContext对象,在recycle-view销毁的时候调用此方法
    forceUpdate callback, reinitSlot 重新渲染recycle-view。callback是渲染完成的回调函数,当before和after这2个slot的高度发生变化时候调用此函数,reinitSlot设置为true。当item的宽高发生变化的时候也需要调用此方法。
    getBoundingClientRect index 获取某个数据项的在长列表中的位置,返回{left, top, width, height}的Object。
    getScrollTop 获取长列表的当前的滚动位置。
    transformRpx rpx 将rpx转化为px,返回转化后的px整数。itemSize返回的宽高单位是px,可以在这里调用此函数将rpx转化为px,参数是Number,例如ctx.transformRpx(140),返回70。注意,transformRpx会进行四舍五入,所以transformRpx(20) + transformRpx(90)不一定等于transformRpx(110)
    getViewportItems inViewportPx 获取在视窗内的数据项,用于判断某个项是否出现在视窗内。用于曝光数据上报,菜品和类别的联动效果实现。参数inViewportPx表示距离屏幕多少像素为出现在屏幕内,可以为负值。
    getList 获取到完整的数据列表

    itemSize使用

    itemSize可以为包含{width, height}的Object,所有数据只有一种宽高信息。如果有多种,则可以提供一个函数,长列表组件会调用这个函数生成每条数据的宽高信息,如下所示:

    function(item, index) {
        return {
            width: 195,
            height: item.azFirst ? 130 : 120
        }
    }

    Tips

    1. recycle-view设置batch属性的值必须为{{batchSetRecycleData}}。
    2. recycle-item的宽高必须和itemSize设置的宽高一致,否则会出现跳动的bug。
    3. recycle-view设置的高度必须和其style里面设置的样式一致。
    4. createRecycleContext(options)的id参数必须和recycle-view的id属性一致,dataKey参数必须和recycle-item的wx:for绑定的变量名一致。
    5. 不能在recycle-item里面使用wx:for的index变量作为索引值的,请使用{{item.__index__}}替代。
    6. 不要通过setData设置recycle-item的wx:for的变量值,建议recycle-item设置wx:key属性。
    7. 如果长列表里面包含图片,必须保证图片资源是有HTTP缓存的,否则在滚动过程中会发起很多的图片请求。
    8. 有些数据不一定会渲染出来,使用wx.createSelectorQuery的时候有可能会失效,可使用RecycleContext的getBoundingClientRect来替代。
    9. 当使用了useInPage参数的时候,必须在Page里面定义onPageScroll事件。
  4. transformRpx会进行四舍五入,所以transformRpx(20) + transformRpx(90)不一定等于transformRpx(110)

  5. 如果一个页面有多个长列表,必须多设置batch-key属性,每个的batch-key的值和batch属性的变量必须不一致。例如

<recycle-view batch="{{batchSetRecycleData}}" batch-key="batchSetRecycleData"></recycle-view>
<recycle-view batch="{{batchSetRecycleData1}}" batch-key="batchSetRecycleData1"></recycle-view>

About

recycle-view: a wechat miniprogram custom component

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  
四级警长是什么级别 梦见玻璃碎了什么意思 肝火上炎吃什么中成药 眼压高吃什么药 吃什么补钙最快
距骨在什么位置 柠檬泡水喝有什么功效 弱冠之年是什么意思 后腰出汗多是什么原因 回民为什么不能吃猪肉
福生无量是什么意思 上海的特产是什么 六月初二是什么星座 胡牌是什么意思 媱五行属什么
蜗牛爱吃什么 眉心中间有痣代表什么 脚底心发热是什么原因 吃什么能快速补血 153是什么意思
瞳孔缩小见于什么病hcv7jop5ns6r.cn 什么叫主动脉硬化hcv9jop3ns6r.cn 什么叫高危性行为hcv8jop6ns8r.cn hc是什么意思hcv9jop7ns9r.cn 麝香是什么东西hcv8jop9ns5r.cn
男人喜欢什么姿势hcv9jop0ns1r.cn 梦见下大雪是什么意思hcv9jop6ns8r.cn 点天灯是什么意思sscsqa.com 高什么远瞩hcv9jop3ns6r.cn 女生的下面叫什么jasonfriends.com
大雄宝殿供奉的是什么佛hcv9jop2ns2r.cn 五月初七是什么星座hcv8jop1ns2r.cn 牙酸是什么原因hcv8jop4ns9r.cn 经期吃什么水果好hcv9jop8ns0r.cn 梦见别人开车撞死人是什么意思hcv9jop8ns2r.cn
鲱鱼是什么鱼hcv8jop3ns4r.cn 吃什么对眼睛有好处hcv7jop5ns2r.cn 岁月如歌下一句是什么hcv8jop6ns3r.cn 应景是什么意思hcv8jop4ns9r.cn 姜枣茶什么时间喝最好huizhijixie.com
百度