Skeleton骨架屏
在数据加载时提供占位效果
INFO
基础用法示例为图片加载的占位操作
需要在 Skeleton 组件外部放一个不可见的图片 用于请求加载
当 loading 初始值为 true 时,因为 渲染时机 会使得 content插槽 里面的图片不会进行渲染
若不进行此操作 图片将永远无法加载
作用于Skeleton上的css无效
直接在 Skeleton 上设置样式是无效的,因为内部不会有任何元素去接受其样式
简而言之 Skeleton 组件不会也不应该对用户布局产生任何影响,它仅仅相对于一个标识符,以此完成骨架屏的效果,仅此而已
基础用法
Skeleton的使用不太同于其它框架,在 li-daisy 中Skeleton作为一个容器,然后借助 daisyUI 的 skeleton 去实现具体的骨架屏效果例子中的
skeleton是加了前缀的类名,具体类名取决于你项目中的 daisyUI 的配置
<template>
<div>
<img class="sr-only" src="https://picsum.photos/300/300" @load="handleImgLoad" />
<Skeleton :loading="loading" :delay="500">
<template #content>
<div class="space-y-3">
<img
v-for="i in 3"
:key="i"
class="mx-auto w-30 h-30 rounded-md"
src="https://picsum.photos/300/300"
/>
</div>
</template>
<template #skeleton>
<div class="space-y-3">
<div v-for="i in 3" :key="i" class="skeleton mx-auto w-30 h-30 rounded-md" />
</div>
</template>
</Skeleton>
</div>
</template>
<script setup lang="ts">
import { Skeleton } from 'li-daisy'
import { ref } from 'vue'
const loading = ref(true)
const handleImgLoad = () => {
loading.value = false
}
</script>设置遮罩
有时为了让骨架屏更加有层次感,使用遮罩也是必要的
以下代码给出设置遮罩可行的方案
具体思路便是在
skeleton插槽中使用一个relative的父级以及一个absolute的遮罩遮罩层使用渐变背景
bg-gradient-to-t从底部向顶部渐变,营造出内容逐渐淡出的视觉效果通过
pointer-events-none确保遮罩不会拦截用户的交互操作
z-10确保遮罩在骨架屏内容之上显示
关于遮罩颜色选择:
- 遮罩的过渡颜色应与骨架屏的背景色保持一致,通常使用
from-base-100或from-base-200 - 如果骨架屏位于卡片或容器中,建议使用该容器的背景色类,如示例中的
from-base-100 - 调整
from-60%或from-50%的百分比值可以控制渐变的起始位置,数值越大渐变越靠下 - 如果遮罩效果不明显,可以尝试增加不透明度或调整起始位置,如
from-base-100/90 from-40%
<template>
<div class="space-y-6">
<Skeleton :loading="true" :delay="1000">
<template #skeleton>
<div class="relative border border-base-300 rounded-box bg-base-100 overflow-hidden">
<ul class="list flex flex-col divide-y divide-base-300">
<li v-for="i in 3" :key="i" class="p-4 space-y-3">
<div class="grid items-center gap-4" style="grid-template-columns: auto 1fr auto">
<div class="skeleton opacity-60 size-10 rounded-full"></div>
<div class="space-y-2">
<div class="skeleton opacity-60 w-36 h-3 rounded-box"></div>
<div class="skeleton opacity-60 w-24 h-2 rounded-box"></div>
</div>
<div class="skeleton opacity-60 h-8 w-8 rounded-box"></div>
</div>
<div class="skeleton opacity-60 w-[50%] h-3 rounded-box"></div>
</li>
</ul>
<div
class="absolute bottom-0 left-0 right-0 top-32 pointer-events-none z-10 bg-gradient-to-t from-base-100 from-60% to-transparent"
></div>
</div>
</template>
</Skeleton>
</div>
</template>
<script setup lang="ts">
import { Skeleton } from 'li-daisy'
</script>设置count
组件并未提供设置
count的属性,而是建议手动去设置数量,因为此时可以确保布局的可控性比如 上述例子 中就是使用简单的
v-for去实现类似的效果这样最大的好处就是可以极大统一
content和skeleton插槽中的元素结构
设置delay
通过设置
delay来设置延迟效果当网络请求较快时,较容易出现闪烁的现象,通过设置这项,用户可以得到较好的视觉效果,默认值为
300(单位为ms)
渲染说明
注意:由于骨架屏采用客户端条件渲染,爬虫访问时将获取到骨架屏占位符而非实际内容
如需 SEO 支持,建议在服务端预加载数据或采用其他 SSR 方案。
说明:
skeleton和content插槽基于loading值进行条件渲染(使用v-if)当
loading为false时,骨架屏隐藏,内容显示由于使用
v-if因此可以安全地在content插槽中直接访问异步数据,无需额外的空值检查
API
Attributes
Skeleton
| 属性值 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| loading | 加载状态 | boolean | - |
| delay | 延迟时间/ms | number | 300 |
| count | 骨架数目 | number | 1 |
Slots
Skeleton
| 插槽名 | 说明 |
|---|---|
| content | 实际要渲染的内容 |
| skelton | 骨架屏内容 |