微信小程序

微信开发者工具
tabbar
Tabbar
Tabbar组件,也可以用来作为小程序的自定义Tabbar使用

代码引入
在 page.json 中引入组件


{
  "usingComponents": {
    "mp-tabbar": "weui-miniprogram/tabbar/tabbar"
  }
}

{
  "usingComponents": {
    "mp-tabbar": "../components/tabbar/tabbar"
  },
  "navigationBarTitleText": "UI组件库"
}

属性列表
属性 类型 默认值 必填 说明
ext-class string 否 添加在组件内部结构的class,可用于修改组件内部的样式
list array 否 Tabbar的项的数组,按照规范,至少要有2个Tabbar项
current number 0 否 当前选中的Tabbar项的下标
bindchange eventhandler 否 Tabbar项发生改变的时候触发此事件,detail为{index, item},index是Tabbar下标,item是对应的Tabbar项的配置
list属性是对象数组,每一项表示一个Tabbar项,其字段含义为

字段名 类型 默认值 必填 说明
text string 是 Tabbar项的标题
iconPath string 否 Tabbar项的icon图片路径,建议使用绝对路径,相对路径要相对于组件所在目录的。
selectedIconPath string 否 Tabbar项选中时的icon,建议使用绝对路径,相对路径要相对于组件所在目录的。
badge string 否 是否显示Tabbar的右上角的Badge
Navigation
Navigation是小程序的顶部导航组件,当页面配置navigationStyle设置为custom的时候可以使用此组件替代原生导航栏。

代码引入
在 page.json 中引入组件

{
  "usingComponents": {
    "mp-navigation-bar": "weui-miniprogram/navigation-bar/navigation-bar"
  }
}
{
    "usingComponents": {
        "mp-navigation-bar": "../components/navigation-bar/navigation-bar"
    },
    "navigationStyle": "custom",
    "navigationBarTitleText": "UI组件库"
}

属性列表
属性 类型 默认值 必填 说明
ext-class string 否 添加在组件内部结构的class,可用于修改组件内部的样式
title string 否 导航标题,如果不提供,则名为center的slot有效
back boolean true 否 是否显示返回按钮,默认点击按钮会执行navigateBack,如果为false,则名为left的slot有效
delta number 1 否 当back为true的时候有效,表示navigateBack的delta参数
background string #f8f8f8 否 导航背景色
color string 否 导航颜色
loading boolean 否 是否显示标题左侧的loading
show boolean 否 显示隐藏导航,隐藏的时候navigation的高度占位还在
animated boolean 否 显示隐藏导航的时候是有opacity过渡动画
bindback eventhandler 否 在back为true时,点击back按钮触发此事件,detail包含delta
Slot
名称 描述
left 左侧slot,在back按钮位置显示,当back为false的时候有效
center 标题slot,在标题位置显示,当title为空的时候有效
right 在导航的右侧显示
Searchbar
搜索组件Searchbar提供搜索的功能,并展示搜索的结果。

代码引入
在 page.json 中引入组件

{
  "usingComponents": {
    "mp-searchbar": "weui-miniprogram/searchbar/searchbar"
  }
}

属性列表
属性 类型 默认值 必填 说明
ext-class string 否 添加在组件内部结构的class,可用于修改组件内部的样式
focus boolean false 否 是否在组件开始创建的时候focus搜索输入框
placeholder string 搜索 否 搜索输入框的placeholder
value string 否 搜索输入框的默认值
search function 是 输入过程不断调用此函数得到新的搜索结果,参数是输入框的值value,返回Promise实例
throttle number 500 否 调用search函数的间隔,单位ms
cancelText string 取消 否 取消按钮的文本
cancel boolean true 否 是否显示取消按钮
bindfocus eventhandle 否 在输入框focus的时候触发事件
bindblur eventhandle 否 在输入框blur的时候触发事件
bindclear eventhandle 否 在clear按钮点击的时候触发事件
bindinput eventhandle 否 在输入框输入过程中触发事件
bindselectresult eventhandle 否 在选择搜索结果的时候触发事件
修改组件内部样式
每个组件可以设置ext-class这个属性,该属性提供设置在组件WXML顶部元素的class,组件的addGlobalClass的options都设置为true,所以可以在页面设置wxss样式来覆盖组件的内部样式。需要注意的是,如果要覆盖组件内部样式,必须wxss的样式选择器的优先级比组件内部样式优先级高。 addGlobalClass在基础库2.2.3开始支持。

适配 DarkMode
在根结点(或组件的外层结点)增加属性 data-weui-theme=“dark”,即可把 WeUI 组件切换到 DarkMode 的表现,如:

...

也可以参考库中提供的 Demo。

recycle-view
小程序长列表组件

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

背景
目前小程序会有不少的应用场景里会用到无限长列表的交互,当一个页面展示很多信息的时候,会造成小程序页面的卡顿以及白屏。原因有如下几点:

列表数据很大,首次 setData 的时候耗时高
渲染出来的列表 DOM 结构多,每次 setData 都需要创建新的虚拟树、和旧树 diff 操作耗时都比较高
渲染出来的列表 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
使用方法
安装组件

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"
  }
}

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,以提升列表的渲染性能。

页面 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
        }
    }
})

页面必须通过 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表示距离屏幕多少像素为出现在屏幕内,可以为负值。
其中 itemSize 的使用

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

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

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

<recycle-view batch="{{batchSetRecycleData}}" batch-key="batchSetRecycleData"></recycle-view>
<recycle-view batch="{{batchSetRecycleData1}}" batch-key="batchSetRecycleData1"></recycle-view>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹筱君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值