vue实现首页骨架屏
实现骨架屏的基本思路
骨架屏(Skeleton Screen)是一种页面加载优化技术,通过在内容完全加载前展示占位图形,提升用户体验。Vue中实现骨架屏通常有以下几种方式:
使用CSS实现基础骨架屏
通过纯CSS编写骨架屏样式,适用于简单场景:
<template>
<div class="skeleton-container">
<div class="skeleton-header"></div>
<div class="skeleton-content"></div>
<div class="skeleton-footer"></div>
</div>
</template>
<style>
.skeleton-container {
width: 100%;
}
.skeleton-header {
height: 60px;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: shimmer 1.5s infinite;
}
.skeleton-content {
height: 300px;
margin: 20px 0;
background: #f0f0f0;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
</style>
使用第三方库vue-skeleton-webpack-plugin
该插件能自动生成骨架屏并与路由结合:
-
安装插件:

npm install vue-skeleton-webpack-plugin --save-dev -
创建骨架屏组件Skeleton.vue:
<template> <div class="skeleton"> <!-- 你的骨架屏结构 --> </div> </template> -
配置vue.config.js:
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');
module.exports = { configureWebpack: { plugins: [ new SkeletonWebpackPlugin({ webpackConfig: { entry: { app: path.join(__dirname, './src/Skeleton.vue') } }, minimize: true, quiet: true }) ] } }

### 动态切换骨架屏和真实内容
结合v-if控制显示时机:
```html
<template>
<div>
<div v-if="loading" class="skeleton">
<!-- 骨架屏内容 -->
</div>
<div v-else>
<!-- 真实内容 -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
loading: true
}
},
mounted() {
this.fetchData().then(() => {
this.loading = false
})
}
}
</script>
骨架屏动画优化
添加加载动画提升视觉效果:
.skeleton-item {
background: linear-gradient(90deg, #f2f2f2 25%, #e6e6e6 37%, #f2f2f2 63%);
background-size: 400% 100%;
animation: skeleton-loading 1.4s ease infinite;
}
@keyframes skeleton-loading {
0% { background-position: 100% 50%; }
100% { background-position: 0 50%; }
}
响应式骨架屏设计
针对不同屏幕尺寸调整骨架屏:
@media (max-width: 768px) {
.skeleton-item {
height: 100px;
}
}
@media (min-width: 769px) {
.skeleton-item {
height: 200px;
}
}
与路由结合的进阶实现
在路由守卫中控制骨架屏显示:
router.beforeEach((to, from, next) => {
store.commit('SET_LOADING', true)
next()
})
router.afterEach(() => {
setTimeout(() => {
store.commit('SET_LOADING', false)
}, 500)
})
以上方法可根据实际项目需求组合使用,关键是要确保骨架屏结构与真实页面布局一致,并在数据加载完成后平滑过渡到真实内容。






