# 骨架屏
骨架屏是页面的一个空白版本,通常会在页面完全渲染之前,通过一些灰色的区块大致勾勒出轮廓,待数据加载完成后,再替换成真实的内容。通常在小程序中,我们需要手工维护骨架屏的代码,当业务变更时,同样需要对骨架屏代码进行调整。为了开发的便利,开发者工具提供了自动生成骨架屏代码的能力。
# 运行环境
下载并安装 1.03.2006032 或 1.04.2006032 以上版本的开发者工具
# 使用方法
工具可以为当前正在预览的页面生成骨架屏代码。工具入口位于模拟器面板右下角三点处。
点击生成骨架屏,将有弹窗提示是否允许插入骨架屏代码。确定后将在当前页面同级目录下生成 page.skeleton.wxml
和 page.skeleton.wxss
两个文件,分别为骨架屏代码的模板和样式。
骨架屏代码通过小程序模板(template)的方式引入 以 pages/index/index
页面为例,引入方式如下。
<!-- pages/index/index.wxml 引入模板 -->
<import src="index.skeleton.wxml"/>
<template is="skeleton" wx:if="{{loading}}" data="{{}}"/>
/* pages/index/index.wxss 中引入样式 */
@import "index.skeleton.wxss";
示例代码:https://developers.weixin.qq.com/s/3AQoEBmh7XhF
# 显示与隐藏
与普通的模板相同,通过 wx:if
控制显示隐藏。
# 生成配置
可在 project.config.json
增加字段 skeletonConfig
进行骨架屏相关配置,页面配置会覆盖掉全局配置。
// project.config.json
{
"skeletonConfig": {
"global": {
// 默认的全局配置
"loading": "",
"outline": {
"remain": false,
"replace": "none"
},
"text": {
"color": "#EEEEEE"
},
"image": {
"shape": "",
"color": "#EFEFEF",
"shapeOpposite": []
},
"button": {
"color": "#EFEFEF",
"excludes": []
},
"pseudo": {
"color": "#EFEFEF",
"shape": "circle",
"shapeOpposite": []
},
"excludes": [],
"remove": [],
"empty": [],
"hide": [],
"grayBlock": [],
"showNative": false,
"backgroundColor": "transparent",
"mode": "fullscreen",
"templateName": "skeleton",
"cssUnit": "rpx",
"decimal": 4,
},
"pages": {
"pages/index/index": {
// 页面配置,key 为页页面路径
}
}
}
具体配置如下。开发者可根据需要设置文字、图片、按钮的颜色和形状,同时可根据 excludes
、remove
、hide
等忽视或隐藏部分页面元素,以获取更优的展示效果。
字段 | 类型 | 必填 | 默认值 | 说明 |
---|---|---|---|---|
loading | String | No | spin | 骨架屏显示时的动画:spin chiaroscuro shine |
outline | Object | No | 该配置接受一个 remain Boolean 字段,默认为 true ,表示保持边框颜色,为 false 时,用 replace 字段替代 style.border | |
text | Object | No | 该配置接受一个 color 字段,用于决定骨架页面中文字块的的颜色,颜色值支持 16 进制。 | |
image | Object | No | 该配置接受 3 个字段,color 、shape 、shapeOpposite 。color 和 shape 用于确定骨架页面中图片块的颜色和形状,颜色值支持 16 进制,形状支持两个枚举值,circle (圆形)和 rect (矩形)。shapeOpposite 字段接受一个数组,数组中每个元素是一个 DOM 选择器,用于选择 DOM 元素,被选择 DOM 的形状将和配置的 shape 形状相反,例如,配置的是 rect 那么,shapeOpposite 中的图片块将在骨架页面中显示成 circle 形状(圆形) | |
button | Object | No | 该配置接受两个字段,color 和 excludes 。color 用来确定骨架页面中被视为按钮块的颜色,excludes 接受一个数组,数组中元素是 DOM 选择器,用来选择元素,该数组中的元素将不被视为按钮块。 | |
pseudo | Object | No | 该配置接受两个字段,color 和 shape 。color 用来确定骨架页面中被视为伪元素块的颜色,shape 用来设置伪元素块的形状,接受两个枚举值:circle 和 rect。 | |
excludes | Array | No | [] | 如果你有不需要进行骨架处理的元素,那么将该元素的 CSS 选择器写入该数组。 |
remove | Array | No | [] | 不需要生成页面骨架,且需要从 DOM 中移除的元素,配置值为移除元素的 CSS 选择器。 |
hide | Array | No | [] | 不需要移除,但是通过设置其透明度为 0,来隐藏该元素,配置值为隐藏元素的 CSS 选择器。 |
empty | Array | No | [] | 该数组中元素是 CSS 选择器,被选择的元素将被清空子元素 |
grayBlock | Array | No | [] | 该数组中元素是 CSS 选择器,被选择的元素将被被插件处理成一个色块,色块的颜色和按钮块颜色一致。内部元素将不再做特殊处理,文字将隐藏 |
showNative | Boolean | No | false | 显示原生组件,为 false 时原生组件被处理为 view。 |
backgroundColor | String | No | transparent | 骨架屏背景色 |
mode | String | No | fullscreen | 默认为使用绝对定位占满全屏。当对自定义组件使用,作为局部加载的样式时,可设为 auto ,高度随内容撑开 |
templateName | String | No | skeleton | 骨架屏模板的 name 值 |
cssUnit | String | No | rpx | 支持的枚举值:rpx, rem, vw, vh, vmin, vmax |
decimal | Number | No | 4 | 生成骨架页面中 css 值保留的小数位数,默认值是 4 |
原生组件包括 camera
, live-player
, live-pusher
, video
, map
, canvas
, picker
, input
, textarea
。
# 自定义属性
有时我们需要让骨架的某块内容显示特定的背景色,可以通过 data-skeleton-bgColor="#ff00000"
这样的方式来指定。
在处理列表的时候,为了尽可能美观,我们对列表进行了同化处理,后面的子项都是第一个子项的克隆。由于小程序的列表不是通过 ul/ol
标签来声明的,这里借助 data-*
属性进行标示。考虑到列表容器内可能插入其它结构,有如下两种声明方式:data-skeleton-list
的直接子节点将被处理成第一项的克隆;data-skeleton-li
属性相同的元素被认为是同一列表的子项。
<!-- 方式一:列表容器内容均为列表项 -->
<view wx:for="{{array}}" data-skeleton-list>
<view class="list-item">子项内容</view>
</view>
<!-- 方式二:列表容器中插入了其它元素 -->
<view wx:for="{{array}}">
<view class="other-block">其它</view>
<view class="list-item" data-skeleton-li="goods">子项内容</view>
<view class="list-item" data-skeleton-li="goods">子项内容</view>
<view class="list-item" data-skeleton-li="goods">子项内容</view>
</view>
此外,页面可能被划分成不同的区域,通过不同的请求来获取数据,它们的响应时间也不一致。骨架屏原本是一个整体,我们希望对其进行拆分,哪条请求返回了,就替换掉对应区域的骨架屏为真实内容,达到渐进式加载的效果。声明 data-skeleton-hide
属性的节点生成骨架屏时会被替换成 hidden
属性,开发者可通过 data
控制其显示/隐藏。 需要注意的是,为了使真实数据的位置与骨架屏一致,此时应使用 absolute
方式定位页面主模块,详情参考示例 demo
。
<!-- 原 wxml 内容 -->
<view data-skeleton-hide="hideBlock1"></view>
<view data-skeleton-hide="hideBlock2"></view>
<!-- 骨架屏 wxml 内容 -->
<view hidden="{{hideBlock1}}"></view>
<view hidden="{{hideBlock2}}"></view>
# Tips
- 骨架屏仅包括页面首屏中的可见区域,对于横向滚动的
swiper
等容器,超出屏幕的子元素将被忽略; - 骨架屏的布局复用开发者的页面布局,需要骨架屏自适应页面尺寸时,页面布局应采用 rpx 等自适应方案;
- 部分组件如
movable-view
、movable-area
、rich-text
、editor
、picker
、picker-view
、picker-view-column
、ad
、officail-account
和open-data
无法生成理想的骨架效果,可通过添加一个父容器,结合 grayBlock、empty 等配置,将其置灰。 - 请勿修改自动生成的骨架屏的代码,当效果不理想时,建议调整相关配置,这样当页面变更时,仍可自动生成;
- 生成的骨架屏代码中会包含预览时的页面数据,将被用来填充页面;
- 骨架屏通常用于商品列表、新闻列表等页面,对于动画/原生组件较多的页面展示效果不佳;
- 该能力除用于展示首屏骨架外,也可作为局部加载的
loading
样式,可灵活使用;