Skeleton
Place a skeleton where content is loading. In some scenarios, it provides a better visual experience than a loading spinner.
Basic Usage
Basic skeleton effect.
<template>
<b-skeleton></b-skeleton>
</template>More Parameters
Configure the number of skeleton paragraph rows to more closely match the real rendering. The displayed count will be one more than the number passed in; the first row is rendered as a leading paragraph at 33% width.
<template>
<b-skeleton :rows="5"></b-skeleton>
</template>Animation Effect
Can display animation effects.
<template>
<b-skeleton animation></b-skeleton>
</template>Custom
Use slots to define custom templates, allowing you to build a skeleton that closely matches the real DOM structure.
<template>
<b-skeleton style="width: 240px" animation>
<template #template>
<b-skeleton-item variant="image" style="width: 240px; height: 240px" />
<div style="padding: 14px">
<b-skeleton-item variant="p" style="width: 50%" />
<div flex="main:justify cross:center">
<b-skeleton-item variant="text" style="margin-right: 16px" />
<b-skeleton-item variant="text" style="width: 30%" />
</div>
</div>
</template>
</b-skeleton>
</template>Loading loading
After loading completes, display the real UI via the slot.
User Info
User Info Content
User Info Content
User Info Content
2026-05-18
<template>
<div>
<div class="mb-15">
<b-button @click="show">Show after 2s</b-button>
</div>
<b-skeleton style="width: 350px" :loading="loading" animation>
<template #template>
<div flex="cross:center" style="margin-bottom: 8px">
<b-skeleton-item variant="circle" style="width: 36px; margin-right: 8px" />
<div style="width: 200px">
<div flex="main:justify cross:center">
<b-skeleton-item variant="text" style="margin-right: 16px" />
<b-skeleton-item variant="text" style="width: 30%" />
</div>
</div>
</div>
<b-skeleton />
</template>
<template #default>
<div style="width: 350px">
<div flex="cross:center" style="margin-bottom: 8px">
<b-skeleton-item variant="circle" style="width: 36px; margin-right: 8px" />
<div style="width: 200px">User Info</div>
</div>
<p>User Info Content</p>
<p>User Info Content</p>
<p>User Info Content</p>
<p>{{ currentDate }}</p>
</div>
</template>
</b-skeleton>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import dayjs from 'dayjs'
const loading = ref(false)
const currentDate = ref(dayjs().format('YYYY-MM-DD'))
function show() {
loading.value = true
setTimeout(() => {
loading.value = false
}, 2000)
}
</script>Skeleton Props
| Parameter | Description | Type | Options | Default |
|---|---|---|---|---|
| animated | Whether to useanimation | boolean | true / false | false |
| count | Number of templates to render; use the smallest number possible | number | integer | 1 |
| loading | Whether to show the real DOM structure | boolean | true / false | false |
| rows | Number of skeleton paragraph rows | number | Positive integer | 3 |
| throttle | Delay before rendering the placeholder DOM, in milliseconds | number | Positive integer | 0 |
Skeleton Item Attributes
| Parameter | Description | Type | Options | Default |
|---|---|---|---|---|
| variant | Style of the currently displayed placeholder element | Enum(string) | p / text / h1 / h2 / h5 / text / caption / button / image / circle / rect | text |
Skeleton Slots
| name | description |
|---|---|
| default | Used to display the real UI |
| template | Used to display custom placeholders |