You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3实现Skeleton Loader:解决数据加载过快时闪烁问题

解决方案

核心思路是结合最小延迟阈值与图片加载完成事件,只有当两个条件都满足时才切换到真实内容。这样既避免快速加载时的骨架屏闪烁,又不会在慢加载场景下额外增加等待时间。

步骤1:调整状态变量

定义两个响应式变量,分别跟踪图片是否加载完成、是否过了最小延迟时间:

import { ref, onMounted } from 'vue';

const isLoaded = ref(false);
const delayPassed = ref(false);

步骤2:修改加载逻辑

在onMounted中同时设置延迟定时器和图片加载监听:

onMounted(() => {
  // 最小延迟阈值,可根据视觉体验调整(建议150-200ms)
  const minDelay = 200;
  
  // 触发延迟标记
  setTimeout(() => {
    delayPassed.value = true;
  }, minDelay);

  // 加载图片并监听完成事件
  const img = new Image(getSrc('.jpg'));
  img.onload = () => {
    isLoaded.value = true;
  };
  // 可选:处理图片加载失败的情况,避免骨架屏一直显示
  img.onerror = () => {
    isLoaded.value = true;
    // 这里也可以添加错误状态,显示占位图
  };
  img.src = getSrc('.jpg');
});

步骤3:更新模板判断逻辑

只有当图片加载完成且过了最小延迟时间时,才显示真实内容;否则显示骨架屏(同时保留原有的pending状态判断):

<ItemCardSkeleton v-if="!pending || !(isLoaded && delayPassed)" />
<template v-else>
    <img
        class="card__image"
        :src="getSrc('.jpg')"
        :alt="recipe.alt"
        width="15.625rem"
        loading="lazy" />
    <div class="card__content">
        <h2 class="card__title">{{ recipe.title }}</h2>
    </div>
</template>

逻辑说明

  • 当图片加载耗时超过设定的最小延迟(比如网络慢):图片加载完成时,延迟标记已经为true,会立刻切换到真实内容,无额外等待。
  • 当图片加载耗时小于最小延迟(比如从缓存加载):会等够延迟时间再切换,避免骨架屏刚渲染就消失的闪烁问题。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 14:15:11