骨架屏在Vue中怎么实现才不会闪屏?

Air-爱书 阅读 65

我用 Vue 做了个商品列表页,数据从接口拉取,想加个骨架屏提升体验。但每次加载完数据后,骨架屏消失、真实内容出现的瞬间会“闪一下”,看起来特别卡。我试过用 v-if="loading" 控制骨架屏和真实内容的切换,但还是有闪烁。

是不是应该用 v-show?或者需要配合 CSS 动画?有没有人遇到过类似问题?我的骨架屏是用 div 模拟的占位块,结构大概像这样:

<div v-if="loading" class="skeleton">
  <div class="skeleton-item"></div>
  <div class="skeleton-item"></div>
</div>
<div v-else>
  <product-item v-for="item in list" :key="item.id" :data="item" />
</div>
我来解答 赞 12 收藏
二维码
手机扫码查看
1 条解答
百里秀花
骨架屏闪屏的根本原因是v-if会销毁/重建DOM,导致页面重新渲染。直接用v-show代替v-if,同时给骨架屏和真实内容都加上opacity过渡:

<template>
<div class="container">
<!-- 骨架屏:loading时显示 -->
<div v-show="loading" class="skeleton">
<div class="skeleton-item" v-for="i in 4" :key="i"></div>
</div>

<!-- 真实内容:加载完显示 -->
<div v-show="!loading" class="content">
<product-item v-for="item in list" :key="item.id" :data="item" />
</div>
</div>
</template>

<style>
.skeleton, .content {
transition: opacity 0.3s ease;
}
</style>


如果还有轻微闪烁,在数据赋值后加个微小的延迟再隐藏骨架屏:

// 接口返回后
this.list = res.data
setTimeout(() => {
this.loading = false
}, 50)


50ms足够让浏览器完成DOM测量和渲染,闪屏基本消失。
点赞
2026-03-16 21:03