Skeleton骨架屏在Vue中如何正确控制显示时机?

沐岩 Dev 阅读 49

我在用Vue做列表页,数据从接口获取,想加个骨架屏提升体验。但不确定该在什么时候切换骨架屏和真实内容。

目前是用loading变量控制,初始为true,请求完成设为false。但有时候数据很快回来,骨架屏闪一下反而更突兀,有没有更平滑的方案?

这是我的模板结构:

<div v-if="loading">
  <SkeletonItem v-for="i in 5" :key="i" />
</div>
<div v-else>
  <Item v-for="item in list" :key="item.id" :data="item" />
</div>
我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
设计师诗琪
控制骨架屏的显示时机确实是个细节活。你现在的做法虽然简单直接,但在数据加载非常快的情况下确实会出现闪烁的问题。为了提升用户体验,可以稍微调整一下策略。

首先,引入一个延迟机制,只有在加载时间超过一定阈值时才显示骨架屏。这样可以避免数据飞快返回时的短暂闪烁。

具体来说,可以在开始请求时启动一个定时器,设置一个合理的延迟时间(比如300毫秒),在这个时间内如果数据回来了,就不显示骨架屏。如果数据还没有回来,则显示骨架屏。这样既能提升用户体验,也不会让页面显得突兀。

下面是改造后的代码示例:

data() {
return {
loading: false,
list: [],
showSkeleton: false,
};
},
methods: {
fetchData() {
this.loading = true;
const delayTimer = setTimeout(() => {
this.showSkeleton = true;
}, 300); // 设置延迟时间

// 模拟异步请求
setTimeout(() => {
clearTimeout(delayTimer); // 清除定时器
this.list = [/* 你的数据 */];
this.loading = false;
}, 1000); // 模拟1秒后数据返回
},
},
mounted() {
this.fetchData();
},


然后在模板中使用showSkeleton来控制骨架屏的显示:

<div v-if="showSkeleton && loading">
<SkeletonItem v-for="i in 5" :key="i" />
</div>
<div v-else>
<Item v-for="item in list" :key="item.id" :data="item" />
</div>


这样处理后,只有当数据加载时间超过300毫秒时才会显示骨架屏,效率更高,用户感知也更好。
点赞
2026-03-23 08:05
Des.星瑶
这个问题的关键是:骨架屏闪一下的本质是显示时间太短,人眼还没来得及感知就切换了。数据越快回来,这个问题越明显。

你现在的做法是请求完立即切换loading状态,数据如果200ms就回来了,骨架屏只闪了200ms,视觉上就是突兀的一下。解决思路很简单——给骨架屏加个"最短显示时间",让它至少展示一段时间再切换。

最实用的方案是用一个延迟来控制切换时机。我给你改一下逻辑:

首先在data里加两个状态:

data() {
return {
loading: true,
// 记录骨架屏开始显示的时间戳
skeletonStartTime: null,
// 骨架屏最短显示时间,单位毫秒,建议300-500ms
minSkeletonDuration: 300
}
}

然后改造你的请求逻辑:

async fetchList() {
this.loading = true;
this.skeletonStartTime = Date.now();

const res = await api.getList();

// 请求完成后,计算已经显示了多久
const elapsed = Date.now() - this.skeletonStartTime;
const remaining = this.minSkeletonDuration - elapsed;

if (remaining > 0) {
// 如果还没达到最短显示时间,等剩余时间到了再切换
setTimeout(() => {
this.loading = false;
}, remaining);
} else {
// 已经超过最短时间了,立即切换
this.loading = false;
}
}

这个方案的原理很简单:骨架屏一旦显示,就记录开始时间,不管数据什么时候回来,都要保证骨架屏至少展示了300ms。这样即使用户网络很好,也不会出现闪烁问题。

如果想体验更好,还可以加个渐变过渡效果。Vue的transition组件就能搞定:





这样切换的时候是淡入淡出的,骨架屏慢慢消失,内容慢慢出现,体验比直接硬切换柔和很多。

最后提醒一点,最短显示时间别设太长,300-500ms就够了。太长的话网速慢的用户会等得烦躁,这个数值是个平衡点。
点赞
2026-03-17 18:01