1. Skeleton骨架屏
1.1. 在需要等待加载内容的位置设置一个骨架屏, 某些场景下比Loading的视觉效果更好。
1.2. Skeleton Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
animated | 是否使用动画 | boolean | true / false | false |
count | 渲染多少个template, 建议使用尽可能小的数字 | number | integer | 1 |
loading | 是否显示skeleton骨架屏 | boolean | true / false | true |
rows | 骨架屏段落数量 | number | 正整数 | 4 |
throttle | 延迟占位DOM渲染的时间, 单位是毫秒 | number | 正整数 | 0 |
1.3. Skeleton Item Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
variant | 当前显示的占位元素的样式 | Enum(string) | p / text / h1 / h3 / text / caption / button / image / circle / rect
| text |
1.4. Skeleton Slots
name | 说明 |
default | 用来展示真实UI |
template | 用来展示自定义占位符 |
2. Skeleton骨架屏例子
2.1. 使用脚手架新建一个名为element-ui-skeleton折叠面板的前端项目, 同时安装Element插件。
2.2. 编辑index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Skeleton from '../components/Skeleton.vue'
import SlotTemplateSkeleton from '../components/SlotTemplateSkeleton.vue'
import LoadingSkeleton from '../components/LoadingSkeleton.vue'
import CountSkeleton from '../components/CountSkeleton.vue'
import ThrottleSkeleton from '../components/ThrottleSkeleton.vue'
Vue.use(VueRouter)
const routes = [
{ path: '/', redirect: '/Skeleton' },
{ path: '/Skeleton', component: Skeleton },
{ path: '/SlotTemplateSkeleton', component: SlotTemplateSkeleton },
{ path: '/LoadingSkeleton', component: LoadingSkeleton },
{ path: '/CountSkeleton', component: CountSkeleton },
{ path: '/ThrottleSkeleton', component: ThrottleSkeleton }
]
const router = new VueRouter({
routes
})
export default router
2.3. 在components下创建Skeleton.vue
<template>
<div>
<h1>基础用法</h1>
<h4>基础的骨架效果。</h4>
<el-skeleton />
<h1>更多参数</h1>
<h4>可以配置骨架屏段落数量, 以便更接近真实渲染效果。首行会被渲染一个长度33%的段首。</h4>
<el-skeleton :rows="6" />
<h1>动画效果</h1>
<h4>显示动画效果。</h4>
<el-skeleton :rows="6" animated />
</div>
</template>
2.4. 在components下创建SlotTemplateSkeleton.vue
<template>
<div>
<h1>自定义样式</h1>
<h4>Element提供的排版模式有时候并不满足要求, 当您想要用自己定义的模板时, 可以通过一个具名Slot来自己设定模板。</h4>
<el-skeleton style="width: 240px;">
<template slot="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>
</div>
</template>
2.5. 在components下创建LoadingSkeleton.vue
<template>
<div>
<h1>Loading状态</h1>
<h4>当Loading结束之后, 我们往往需要显示真实的UI, 可以通过loading的值来控制是否显示真实的DOM。然后通过具名Slot来设置当loading结束之后需要展示的UI。</h4>
<div style="width: 240px">
<p>
<label style="margin-right: 16px;">切换 Loading</label>
<el-switch v-model="loading" />
</p>
<el-skeleton style="width: 240px" :loading="loading" animated>
<template slot="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>
<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>
<div class="bottom card-header">
<span class="time">{{ currentDate }}</span>
<el-button type="text" class="button">操作按钮</el-button>
</div>
</div>
</el-card>
</template>
</el-skeleton>
</div>
</div>
</template>
<script>
export default {
data () {
return {
loading: true,
currentDate: '2021-06-01'
}
}
}
</script>
2.6. 在components下创建CountSkeleton.vue
<template>
<div>
<h1>渲染多条数据</h1>
<h4>大多时候, 骨架屏都被用来渲染列表, 当我们需要在从服务器获取数据的时候来渲染一个假的UI。利用count这个属性就能控制渲染多少条假的数据在页面上。</h4>
<div style="width: 300px;">
<p><el-button @click="setLoading">点我重新加载</el-button></p>
<el-skeleton style="width: 300px;" :loading="loading" animated :count="3">
<template slot="template">
<el-skeleton-item variant="image" />
<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>
<el-card :body-style="{ padding: '0px', marginBottom: '1px' }" v-for="item in lists" :key="item.name">
<img :src="item.imgUrl" class="image multi-content" style="width: 300px; height: 160px;" />
<div style="padding: 14px;">
<span>{{ item.name }}</span>
<div class="bottom card-header">
<span class="time">{{ currentDate }}</span>
<el-button type="text" class="button">操作按钮</el-button>
</div>
</div>
</el-card>
</template>
</el-skeleton>
</div>
</div>
</template>
<script>
export default {
data () {
return {
loading: true,
currentDate: '2021-06-01',
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>
2.7. 在components下创建ThrottleSkeleton.vue
<template>
<div>
<h1>防止渲染抖动</h1>
<h4>有的时候, API的请求回来的特别快, 往往骨架占位刚刚被渲染, 真实的数据就已经回来了, 用户的界面会突然一闪, 此时为了避免这种情况, 就需要通过throttle属性来避免这个问题。</h4>
<div style="width: 240px">
<p>
<label style="margin-right: 16px;">切换 Loading</label>
<el-switch v-model="loading" />
</p>
<el-skeleton style="width: 240px" :loading="loading" animated :throttle="500">
<template slot="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>
<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>
<div class="bottom card-header">
<span class="time">{{ currentDate }}</span>
<el-button type="text" class="button">操作按钮</el-button>
</div>
</div>
</el-card>
</template>
</el-skeleton>
</div>
</div>
</template>
<script>
export default {
data () {
return {
loading: false,
currentDate: '2021-06-01'
}
}
}
</script>
2.8. 运行项目, 访问http://localhost:8080/#/Skeleton
2.9. 运行项目, 访问http://localhost:8080/#/SlotTemplateSkeleton
2.10. 运行项目, 访问http://localhost:8080/#/LoadingSkeleton
2.11. 运行项目, 访问http://localhost:8080/#/CountSkeleton
2.12. 运行项目, 访问http://localhost:8080/#/ThrottleSkeleton