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

如何用Vue3 Suspense组件实现异步图片加载?

解决Vue3 Suspense配合图片异步加载+骨架屏的问题

你判断的核心问题没错:当前代码无法正常工作是因为async setup()里没有返回Suspense需要等待的Promise,而直接请求图片URL触发CORS是因为跨域图片加载需要正确配置跨域属性。下面是简便且有效的实现方案:

核心思路

通过创建原生Image对象,监听其加载/错误状态,将图片加载过程包装为Promise,让Suspense等待这个Promise完成后再渲染真实图片,同时规避CORS问题。

完整的AsyncImageLoader组件实现

<template>
  <img
    :src="imageUrl"
    alt="Profile Photo"
    style="filter: invert(0); clip-path: circle(38%)"
  />
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "AsyncImageLoader",
  props: {
    imageUrl: {
      type: String,
      required: true,
    },
  },
  async setup(props) {
    // 将图片加载过程包装为Promise,供Suspense等待
    await new Promise((resolve, reject) => {
      const img = new Image();
      // 配置跨域属性,解决跨域图片加载的CORS问题
      img.crossOrigin = "anonymous";
      
      img.onload = () => resolve(null);
      img.onerror = (err) => reject(err);
      
      img.src = props.imageUrl;
    });
  },
});
</script>

关键细节说明

  • Suspense等待逻辑:async setup()中的await会让Suspense持续显示fallback骨架屏,直到图片加载完成的Promise被resolve。
  • CORS问题解决:给Image对象设置crossOrigin = "anonymous",同时要确保图片所在服务器的响应头包含Access-Control-Allow-Origin(允许你的站点域名访问),即可避免跨域错误。
  • 错误处理:如果需要处理图片加载失败的场景,可以在onerror回调中添加错误提示或降级逻辑,比如reject后在组件内捕获错误做对应处理。

父组件代码无需修改

你之前使用Suspense的父组件代码是正确的,保持原样即可:

<div class="w-40">
  <Suspense>
    <AsyncImageLoader :image-url="photoUrl" />
    <template #fallback>
      <SkeletonLoader shape="circle" class="mx-7 h-[106px]" />
    </template>
  </Suspense>
</div>

这样就能实现图片加载完成前显示骨架屏,加载完成后切换为真实图片的效果,同时解决了CORS和Suspense不等待的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 00:32:15