2020-12-21 20:07:48 +08:00
|
|
|
|
## Skeleton 骨架屏
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
在需要等待加载内容的位置设置一个骨架屏,某些场景下比 Loading 的视觉效果更好。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
|
|
|
|
### 基础用法
|
|
|
|
|
|
|
|
|
|
基础的骨架效果。
|
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<template>
|
|
|
|
|
<el-skeleton />
|
|
|
|
|
</template>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### 更多参数
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
可以配置骨架屏段落数量,以便更接近真实渲染效果。显示的数量会比传入的数量多 1,首行会被渲染一个长度 33% 的段首。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<el-skeleton :rows="5" />
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### 动画效果
|
|
|
|
|
|
|
|
|
|
显示动画效果。
|
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<el-skeleton :rows="5" animated />
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### 自定义样式
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
ElementPlus 提供的排版模式有时候并不满足要求,当您想要用自己定义的模板时,可以通过一个具名 Slot 来自己设定模板。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
我们提供了不同的模板单元可供使用,具体可选值请看 API 详细描述。 建议在描述模板的时候,尽量靠近真实的 DOM 结构,这样可以避免 DOM 高度差距引起的抖动。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<template>
|
|
|
|
|
<el-skeleton style="width: 240px">
|
|
|
|
|
<template #template>
|
|
|
|
|
<el-skeleton-item variant="image" style="width: 240px; height: 240px;" />
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<el-skeleton-item variant="p" style="width: 50%" />
|
|
|
|
|
<div
|
|
|
|
|
style="display: flex; align-items: center; justify-items: space-between;"
|
|
|
|
|
>
|
|
|
|
|
<el-skeleton-item variant="text" style="margin-right: 16px;" />
|
|
|
|
|
<el-skeleton-item variant="text" style="width: 30%;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</el-skeleton>
|
|
|
|
|
</template>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### Loading 状态
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
当 Loading 结束之后,我们往往需要显示真实的 UI,可以通过 `loading` 的值来控制是否显示真实的 DOM。然后通过
|
|
|
|
|
具名 Slot 来设置当 loading 结束之后需要展示的 UI。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<template>
|
|
|
|
|
<el-space direction="vertical" alignment="flex-start">
|
|
|
|
|
<div>
|
|
|
|
|
<label style="margin-right: 16px;">切换 Loading</label>
|
|
|
|
|
<el-switch v-model="loading" />
|
|
|
|
|
</div>
|
|
|
|
|
<el-skeleton style="width: 240px" :loading="loading" animated>
|
|
|
|
|
<template #template>
|
|
|
|
|
<el-skeleton-item
|
|
|
|
|
variant="image"
|
|
|
|
|
style="width: 240px; height: 240px;"
|
|
|
|
|
/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<el-skeleton-item variant="h3" style="width: 50%;" />
|
|
|
|
|
<div
|
|
|
|
|
style="display: flex; align-items: center; justify-items: space-between; margin-top: 16px; height: 16px;"
|
|
|
|
|
>
|
|
|
|
|
<el-skeleton-item variant="text" style="margin-right: 16px;" />
|
|
|
|
|
<el-skeleton-item variant="text" style="width: 30%;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #default>
|
|
|
|
|
<el-card :body-style="{ padding: '0px', marginBottom: '1px' }">
|
|
|
|
|
<img
|
|
|
|
|
src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png"
|
|
|
|
|
class="image"
|
|
|
|
|
/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<span>好吃的汉堡</span>
|
2021-02-01 14:48:26 +08:00
|
|
|
|
<div class="bottom card-header">
|
2020-12-21 20:07:48 +08:00
|
|
|
|
<span class="time">{{ currentDate }}</span>
|
|
|
|
|
<el-button type="text" class="button">操作按钮</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</template>
|
|
|
|
|
</el-skeleton>
|
|
|
|
|
</el-space>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { defineComponent } from 'vue'
|
|
|
|
|
|
|
|
|
|
const dayjs = require('dayjs')
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
loading: true,
|
|
|
|
|
currentDate: dayjs().format('YYYY-MM-DD'),
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### 渲染多条数据
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
大多时候, 骨架屏都被用来渲染列表, 当我们需要在从服务器获取数据的时候来渲染一个假的 UI。利用 `count` 这个属性就能控制渲染多少条假的数据在页面上
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
|
|
|
|
:::tip
|
2021-02-26 09:17:02 +08:00
|
|
|
|
请注意, 请尽可能的将 `count` 的大小保持在最小状态, 即使是假的 UI, DOM 元素多了之后, 照样会引起性能问题, 并且在骨架屏销毁时所消耗的时间也会更长(相对的)。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<template>
|
|
|
|
|
<el-space direction="vertical" alignment="flex-start">
|
|
|
|
|
<el-button @click="setLoading">点我重新加载</el-button>
|
|
|
|
|
<el-skeleton style="width: 240px" :loading="loading" animated :count="3">
|
|
|
|
|
<template #template>
|
|
|
|
|
<el-skeleton-item
|
|
|
|
|
variant="image"
|
|
|
|
|
style="width: 400px; height: 267px;"
|
|
|
|
|
/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<el-skeleton-item variant="h3" style="width: 50%;" />
|
|
|
|
|
<div
|
|
|
|
|
style="display: flex; align-items: center; justify-items: space-between; margin-top: 16px; height: 16px;"
|
|
|
|
|
>
|
|
|
|
|
<el-skeleton-item variant="text" style="margin-right: 16px;" />
|
|
|
|
|
<el-skeleton-item variant="text" style="width: 30%;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #default>
|
|
|
|
|
<el-card
|
|
|
|
|
:body-style="{ padding: '0px', marginBottom: '1px' }"
|
|
|
|
|
v-for="item in lists"
|
2021-04-19 10:33:31 +08:00
|
|
|
|
:key="item.name"
|
2020-12-21 20:07:48 +08:00
|
|
|
|
>
|
|
|
|
|
<img :src="item.imgUrl" class="image multi-content" />
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<span>{{ item.name }}</span>
|
2021-02-01 14:48:26 +08:00
|
|
|
|
<div class="bottom card-header">
|
2020-12-21 20:07:48 +08:00
|
|
|
|
<span class="time">{{ currentDate }}</span>
|
|
|
|
|
<el-button type="text" class="button">操作按钮</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</template>
|
|
|
|
|
</el-skeleton>
|
|
|
|
|
</el-space>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { defineComponent } from 'vue'
|
|
|
|
|
|
|
|
|
|
const dayjs = require('dayjs')
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
loading: true,
|
|
|
|
|
currentDate: dayjs().format('YYYY-MM-DD'),
|
|
|
|
|
lists: [],
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted() {
|
|
|
|
|
this.loading = false
|
|
|
|
|
this.lists = [
|
|
|
|
|
{
|
|
|
|
|
imgUrl:
|
|
|
|
|
'https://fuss10.elemecdn.com/a/3f/3302e58f9a181d2509f3dc0fa68b0jpeg.jpeg',
|
|
|
|
|
name: '鹿',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
imgUrl:
|
|
|
|
|
'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
|
|
|
|
|
name: '马',
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
imgUrl:
|
|
|
|
|
'https://fuss10.elemecdn.com/0/6f/e35ff375812e6b0020b6b4e8f9583jpeg.jpeg',
|
|
|
|
|
name: '山狮',
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
setLoading() {
|
|
|
|
|
this.loading = true
|
|
|
|
|
setTimeout(() => (this.loading = false), 2000)
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### 防止渲染抖动
|
|
|
|
|
|
2021-02-26 09:17:02 +08:00
|
|
|
|
有的时候,API 的请求回来的特别快,往往骨架占位刚刚被渲染,真实的数据就已经回来了,用户的界面会突然一闪,此时为了避免这种情况,就需要通过 `throttle` 属性来避免这个问题。
|
2020-12-21 20:07:48 +08:00
|
|
|
|
|
|
|
|
|
:::demo
|
|
|
|
|
|
|
|
|
|
```html
|
|
|
|
|
<template>
|
|
|
|
|
<el-space direction="vertical" alignment="flex-start">
|
|
|
|
|
<div>
|
|
|
|
|
<label style="margin-right: 16px;">切换 Loading</label>
|
|
|
|
|
<el-switch v-model="loading" />
|
|
|
|
|
</div>
|
|
|
|
|
<el-skeleton
|
|
|
|
|
style="width: 240px"
|
|
|
|
|
:loading="loading"
|
|
|
|
|
animated
|
|
|
|
|
:throttle="500"
|
|
|
|
|
>
|
|
|
|
|
<template #template>
|
|
|
|
|
<el-skeleton-item
|
|
|
|
|
variant="image"
|
|
|
|
|
style="width: 240px; height: 240px;"
|
|
|
|
|
/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<el-skeleton-item variant="h3" style="width: 50%;" />
|
|
|
|
|
<div
|
|
|
|
|
style="display: flex; align-items: center; justify-items: space-between; margin-top: 16px; height: 16px;"
|
|
|
|
|
>
|
|
|
|
|
<el-skeleton-item variant="text" style="margin-right: 16px;" />
|
|
|
|
|
<el-skeleton-item variant="text" style="width: 30%;" />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
<template #default>
|
|
|
|
|
<el-card :body-style="{ padding: '0px', marginBottom: '1px' }">
|
|
|
|
|
<img
|
|
|
|
|
src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png"
|
|
|
|
|
class="image"
|
|
|
|
|
/>
|
|
|
|
|
<div style="padding: 14px;">
|
|
|
|
|
<span>好吃的汉堡</span>
|
2021-02-01 14:48:26 +08:00
|
|
|
|
<div class="bottom card-header">
|
2020-12-21 20:07:48 +08:00
|
|
|
|
<span class="time">{{ currentDate }}</span>
|
|
|
|
|
<el-button type="text" class="button">操作按钮</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</el-card>
|
|
|
|
|
</template>
|
|
|
|
|
</el-skeleton>
|
|
|
|
|
</el-space>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { defineComponent } from 'vue'
|
|
|
|
|
|
|
|
|
|
const dayjs = require('dayjs')
|
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
loading: false,
|
|
|
|
|
currentDate: dayjs().format('YYYY-MM-DD'),
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
|
|
|
|
|
### Skeleton Attributes
|
|
|
|
|
|
|
|
|
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
|
|
|
|
| -------- | ------------------------------------------- | ------- | ------------ | ------ |
|
|
|
|
|
| animated | 是否使用动画 | boolean | true / false | false |
|
|
|
|
|
| count | 渲染多少个 template, 建议使用尽可能小的数字 | number | integer | 1 |
|
|
|
|
|
| loading | 是否显示真实的 DOM 结构 | boolean | true / false | false |
|
|
|
|
|
| rows | 骨架屏段落数量 | number | 正整数 | 3 |
|
|
|
|
|
| throttle | 延迟占位 DOM 渲染的时间, 单位是毫秒 | number | 正整数 | 0 |
|
|
|
|
|
|
|
|
|
|
### Skeleton Item Attributes
|
|
|
|
|
|
|
|
|
|
| 参数 | 说明 | 类型 | 可选值 | 默认值 |
|
|
|
|
|
| ------- | ------------------------ | ------------ | -------------------------------------------------------------------- | ------ |
|
|
|
|
|
| variant | 当前显示的占位元素的样式 | Enum(string) | p / text / h1 / h3 / text / caption / button / image / circle / rect | text |
|
|
|
|
|
|
|
|
|
|
### Skeleton Slots
|
|
|
|
|
|
|
|
|
|
| name | description |
|
|
|
|
|
| -------- | -------------------- |
|
|
|
|
|
| default | 用来展示真实 UI |
|
|
|
|
|
| template | 用来展示自定义占位符 |
|