Skeleton 骨架屏

此组件一般用于页面在请求远程数据尚未完成时,页面用灰色块预显示本来的页面结构,给用户更好的体验。
平台差异说明
| APP | H5 | 微信小程序 | 支付宝小程序 | QQ小程序 | ··· |
|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | 适配中 |
代码示例
部分功能示例,具体可参考示例程序以及文档API。
基础用法
此组件主要由 loading 和 skeleton 两个属性控制,骨架屏的具体内容由 skeleton 中的属性决定,这点很重要,理论上只需要按照约定配置好此参数,就可以实现想要的结构
- 通过
loading属性(必选),控制是否加载中状态,如果为true显示骨架屏组件占位,否则显示插槽中的内容 - 通过
skeleton属性,数组形式[Object, Object, ...]- Object.type类型,type的类型有多种,详见下方参数说明,实际上type的意义并不大,除了flex类型外(下面单独说明该用法),其他的类型都可以自定义任意样式,默认
line - Object.num 表示重复数量,默认
1 - Object.gap重复数量之间的垂直间隔,只有Object.num大于1时才生效,默认
20rpx
- Object.type类型,type的类型有多种,详见下方参数说明,实际上type的意义并不大,除了flex类型外(下面单独说明该用法),其他的类型都可以自定义任意样式,默认
html
<template>
<view>
<fu-skeleton :loading="loading" :skeleton="skeleton"></fu-skeleton>
</view>
</template>
<script setup>
import { ref } from 'vue';
// data数据
let loading = ref(true);
let skeleton = [
{ type: 'line', num: 3, gap: '20rpx' }
];
</script>设置自定义样式
通过 skeleton 属性中的 style 属性,可以自定义样式,具体用法如下:
style的类型可以是array、string、object,示例中的演示代码都有体现,样式根据需求自定义style的array类型,例:['height: 25rpx;', null, null],代表第一个line高度为25rpx,其余的line使用默认样式style的string和object类型,实际上都是一样的,都是设置了3个line均使用设置的样式
html
<template>
<view>
<fu-skeleton :loading="loading" :skeleton="skeleton"></fu-skeleton>
</view>
</template>
<script setup>
import { ref } from 'vue';
// data数据
let loading = ref(true);
let skeleton = [
{
type: 'line',
num: 3,
gap: '20rpx',
style: ['width: 100rpx; marginBottom: 20rpx;', 'height: 25rpx;', 'width: 200rpx;'],
// style: 'width: 100rpx; marginBottom: 20rpx;'
// style: {width: '100rpx', marginBottom: '20rpx'}
}
];
</script>设置横向并列布局
通过 skeleton 属性中的 flex 属性,可以设置横向并列布局
Object.children此属性的用法与上述一致,注意:children下不支持再有childrentype还有avatar、coustom类型avatar类型,为了更好理解,增加了头像类型,有自己的默认样式,实际上也可以使用style进行样式自定义coustom类型,如果完全自定义样式的可以使用此类型
html
<template>
<view>
<fu-skeleton :loading="loading" :skeleton="skeleton"></fu-skeleton>
</view>
</template>
<script setup>
import { ref } from 'vue';
// data数据
let loading = ref(true);
let skeleton = [
{
type: 'flex',
num: 1,
children: [
{ type: 'avatar', num: 1, style: 'marginRight: 20rpx;' },
{ type: 'line', num: 2, style: ['width: 100rpx;', null, 'width: 200rpx;'] }
{ type: 'custom', num: 1, style: 'width: 100rpx; height: 200rpx; marginLeft: 20rpx;' }
]
}
];
</script>混合布局 + 插槽内容
- 通过插槽传入展示的内容,当请求结束后,将
loading属性设置为false,此时会隐藏骨架屏组件,同时展示插槽中的内容 skeleton属性还可以是Number,表示上下之间的间距,单位为rpx,25表示上下之间的间距为25rpx
html
<template>
<view class="custom-page">
<fu-skeleton :loading="loading" :skeleton="skeleton" :animate="animate">
<view class="skeleton-wrap__row">
<view class="skeleton-wrap__row1--left">
<fu-image width="140rpx" height="140rpx" src="https://picsum.photos/65/65"></fu-image>
</view>
<view class="skeleton-wrap__row1--right">
<fu-text text="骨架屏" size="28rpx" lines="1"></fu-text>
<fu-text text="骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。" size="28rpx" lines="1" margin="8rpx 0 0"></fu-text>
<fu-text text="提升用户视觉体验" lines="1" size="28rpx" margin="8rpx 0 0"></fu-text>
</view>
</view>
<view class="skeleton-wrap__gap"></view>
<view class="skeleton-wrap__row skeleton-wrap__between">
<fu-image width="114rpx" height="180rpx" src="https://picsum.photos/114/180"></fu-image>
<fu-image width="114rpx" height="180rpx" src="https://picsum.photos/115/180"></fu-image>
<fu-image width="114rpx" height="180rpx" src="https://picsum.photos/116/180"></fu-image>
<fu-image width="114rpx" height="180rpx" src="https://picsum.photos/117/180"></fu-image>
<fu-image width="114rpx" height="180rpx" src="https://picsum.photos/118/180"></fu-image>
</view>
<view class="skeleton-wrap__gap"></view>
<view class="skeleton-wrap__row">
<view class="skeleton-wrap__row2--left">
<fu-text text="骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。" size="28rpx" lines="1" bold></fu-text>
<fu-text text="骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。" lines="1" size="28rpx" margin="8rpx 0 0"></fu-text>
<fu-text text="骨架屏一般用于页面在请求远程数据尚未完成时,在内容加载出来前展示与内容布局结构一致的灰白块,提升用户视觉体验。" lines="1" size="28rpx" margin="8rpx 0 0"></fu-text>
</view>
<view class="skeleton-wrap__row2--right">
<fu-image width="140rpx" height="140rpx" src="https://picsum.photos/180/180"></fu-image>
</view>
</view>
</fu-skeleton>
</view>
</template>
<script setup>
import { ref } from 'vue';
// data数据
const loading = ref(true);
const animate = ref(true);
const skeleton = [
{ type: 'flex', num: 1, children: [{
type: 'custom',
num: 1,
style: 'width: 140rpx; height: 140rpx; marginRight: 30rpx;'
}, {
type: 'line',
num: 3,
style: [null, 'width: 360rpx;', 'width: 200rpx;']
}]
}, 25,
{ type: 'flex', children: [{
type: 'custom',
style: 'width: 114rpx; height: 180rpx;'
}, {
type: 'custom',
style: 'width: 114rpx; height: 180rpx; marginLeft: 30rpx;'
}, {
type: 'custom',
style: 'width: 114rpx; height: 180rpx; marginLeft: 30rpx;'
}, {
type: 'custom',
style: 'width: 114rpx; height: 180rpx; marginLeft: 30rpx;'
}, {
type: 'custom',
style: 'width: 114rpx; height: 180rpx; marginLeft: 30rpx;'
}]
}, 25,
{ type: 'flex', children: [{
type: 'line',
num: 3,
gap: '20rpx',
style: [null, null, 'width: 400rpx;']
}, {
type: 'custom',
style: 'width: 140rpx; height: 140rpx; marginLeft: 30rpx;'
}],
}
];
</script>
<style lang="scss" scoped>
$coverSize: 140rpx;
.skeleton-wrap {
&__row {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
&__row1 {
&--left {
width: $coverSize;
height: $coverSize;
margin-right: 30rpx;
}
&--right {
flex: 1;
}
}
&__row2 {
&--left {
flex: 1;
}
&--right {
width: $coverSize;
height: $coverSize;
margin-left: 30rpx;
}
}
&__between {
justify-content: space-between;
}
&__gap {
height: 25rpx;
}
}
</style>API
Skeleton Props
| 属性名 | 说明 | 类型 | 默认值 | 可选值 |
|---|---|---|---|---|
| loading | 是否显示骨架屏 | Boolean | true | false |
| animate | 是否开启动画 | Boolean | true | false |
| skeleton | 骨架屏配置项,具体用法详见下方Skeleton Options | Array | - | - |
Skeleton Options
| 属性名 | 说明 |
|---|---|
| Object.type | 骨架类型,组件内置了四种: line 段落结构 avatar 头像形状 flex 并列,需要有children属性 custom 自定义类型,理论上和line、avatar并没区别,但可以自定义样式都可以完全自定义样式 |
| Object.num | 重复数量,[{type: 'line', num: 2}] 意思就是2个段落结构骨架 |
| Object.gap | 骨架垂直间距,[{type: 'line', num: 2, gap: '20rpx'}]意思就是2个段落结构骨架的间距均为20rpx。注意:只有Object.num大于1生效 |
| Object.style | 骨架样式,类型是Array/String/Object,Array依次对应重复骨架的样式,数组中也可以使用Object/String,Object/String表示重复的骨架均用此样式,详见下方设置自定义样式 |
| Object.children | 子骨架,只有flex类型才有此属性,详见下方设置横向并列布局 |
| Number | 表示数组上一项和下一项的间隔距离,单位 rpx。详见上方[混合布局 + 插槽内容](#混合布局 + 插槽内容) |
Skeleton Slot
| 名称 | 说明 |
|---|---|
| default | 插槽内容,当请求结束后,将 loading 属性设置为 false,此时会隐藏骨架屏组件,同时展示插槽中的内容 |