n-skeleton 骨架屏
数据返回前的页面结构占位:灰底占位块按「头像 + 标题条 + 段落行」声明式组合,近似还原真实内容排版(文章 / 评论 / 卡片列表等形态),loading 翻 false 时整树切到默认插槽渲染真实内容。呼吸动画常开(animate 可关),底色跟随主题深浅自动切换。
- 零配置即用:
<n-skeleton />出一条居中的标题占位条;开avatar+rows组合出完整文章形态- 组合即形态:
rows=1+ 定宽定高即文本块 / 按钮块;rows-width/rows-height传数组逐行指定宽度 / 高度(多列 / 表格占位、不规则内容块)- 数据就绪切换:
loading翻false渲染 default 插槽的真实内容,骨架与真内容同结构对接不跳版
平台兼容性
| App | H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ小程序 |
|---|---|---|---|---|---|---|
| √ | √ | √ | × | × | × | × |
如何调用
html
<n-skeleton :rows="3" />
API
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| loading | boolean | true | 是否显示骨架占位;false 时渲染 default 插槽的真实内容(数据就绪后翻回) |
| animate | boolean | true | 呼吸动画开关(整体透明度 0.5~1 循环起伏) |
| rows | number | 0 | 段落占位行数 |
| rowsWidth | string / string[] | "100%" | 段落行宽:单值(如 "100%" / "200px")或数组逐行指定;单值为默认 "100%" 时末行自动收窄 70% |
| rowsHeight | number / number[] | 16 | 段落行高(px):单值全行同高,或数组逐行指定(缺项行回落 16) |
| title | boolean | true | 是否显示标题占位条 |
| titleWidth | string | "50%" | 标题条宽度(如 "50%" / "120px") |
| titleHeight | number | 16 | 标题条高度(px) |
| avatar | boolean | false | 是否显示头像占位(左侧圆形 / 方形块) |
| avatarSize | number | 32 | 头像尺寸(px,宽高同值) |
| avatarShape | string | "circle" | 头像形状:circle 圆形 / square 方形 |
| customClass | string | "" | 挂到根节点的额外 class(类需定义在组件样式表内) |
| customStyle | string | "" | 根节点行内样式:排间距(如 "margin:15px 0")走它 |
事件
无(纯占位展示组件,不对外派发事件)。
插槽
| 插槽名 | 说明 |
|---|---|
| default | 真实内容:loading 为 false 时渲染(建议与骨架组合同结构,切换不跳版) |
主题令牌
| 令牌 | 默认值 | 说明 |
|---|---|---|
| --n-skeleton-bg | var(--n-bg-2) | 占位块底色(缺省挂全局表面色,深浅主题自动) |
| --n-skeleton-gap | 12px | 头像与内容区、段落行与行之间的间距 |
| --n-skeleton-title-gap | 20px | 标题条与首段行的衔接间距 |
| --n-skeleton-radius | 4px | 占位条与方头像的圆角 |
实现说明
与参考实现对照的取舍(同类组件功能面取并集、冲突从使用者视角择优融合)
| 机制 | 参考做法 | 本库做法 | 分歧理由 |
|---|---|---|---|
| 形态模型 | 声明式组合(头像 + 标题 + 行)为主流;另有「单块预设」与「页面节点扫描」两派 | 声明式组合 | 组合是超集(rows=1 + 定宽定高即单块);节点扫描在组件样式隔离下扫不到页面节点,结构不可行 |
| 末行收窄 | 参考源文档未记载末行收窄(默认全行同宽) | 默认 "100%" 时末行收 70%;显式非默认单值全程生效,数组精确控制全宽 | 还原真实段落「末行收尾」排版;用户显式表达宽度意图优先(要全宽末行传数组,如 ['100%']) |
| 逐行高度 | 行高支持数组逐行指定 | 收录(与 rowsWidth 数组对称,缺项行回落 16) | 不规则内容块占位需要;宽高同为逐行通道语义一致 |
| 尺寸类型 | 宽高 props 混收 string / number(number 含义随平台) | number = px 定值,string = 百分比 / 带单位(rowsWidth / titleWidth) | 单一类型单一含义,避免「number 在某端是 rpx」歧义 |
| 呼吸动画 | CSS @keyframes 扫光(background-position)/ 原生动画插件过渡 opacity | JS 帧循环驱动整体 opacity(0.5~1,1600ms 周期,页面隐藏停帧) | @keyframes 本库禁用;背景属性动态修改有 App 端已知不重绘问题;帧循环与 n-loading 同构全端一致 |
| 百分比宽度 | nvue 不支持百分比,组件宽度经 DOM 查询换算 px | 直接支持百分比(uvue 全端可用) | 平台已原生支持,无需查询换算链路 |
| 头像对齐 | 头像与内容区垂直居中 | 顶对齐(与标题行对齐) | 贴近真实内容排版(真内容里头像与首行文字对齐),居中会在无标题时头像悬空 |
| 占位底色 | 硬编码浅深双色(随 theme prop 切换)或固定灰 | --n-skeleton-bg 令牌(缺省挂 --n-bg-2,深浅主题自动) | 令牌一处改全局生效;硬编码双色换肤需逐处覆盖 |
| loading 切换 | v-if 切骨架 / 插槽 | 相同 + 装配位挂结构指纹 :key | App 端子节点插拔不重绘的已知问题,结构性增删整树重建绕开 |
| 不收项 | preloadList 预载布局 / outerClass 扫描选择器 / theme 双色 / 单块 type 预设 | 不收 | 节点扫描系能力(隔离下不可行);单块由 rows=1 + 定宽定高组合达成;深浅跟随主题令牌自动,无需独立 theme prop |