跳转到内容

动态导入图片

本地图片必须导入 .astro 文件中才能显示。但有时,你会想或需要动态地导入图片路径,而不是明确地导入每一张图片。

在这个指南中,你将学会如何使用 Vite 的 import.meta.glob 函数动态导入图片。你将构建一个卡片组件,展示一个人的姓名、年龄和照片。

  1. src 目录下创建一个新的 assets 文件夹,并将你的图片添加到这个新文件夹中。

    • 文件夹src/
      • 文件夹assets/
        • avatar-1.jpg
        • avatar-2.png
        • avatar-3.jpeg
  2. 为你的卡片创建一个新的 Astro 组件,并导入 <Image /> 组件。

    src/components/MyCustomCardComponent.astro
    ---
    import { Image } from 'astro:assets';
    ---
  3. 指定组件将接收的 props,以便在每张卡片上显示必要的信息。如果你在项目中使用 TypeScript,你还可以选择定义它们的类型。

    src/components/MyCustomCardComponent.astro
    ---
    import { Image } from 'astro:assets';
    interface Props {
    imagePath: string;
    altText: string;
    name: string;
    age: number;
    }
    const { imagePath, altText, name, age } = Astro.props;
    ---
  4. 创建一个新的 images 变量并使用 import.meta.glob 函数,它将返回 assets 文件夹内所有图片路径的对象。你还需要导入 ImageMetadata 类型来帮助定义 images 变量的类型。

    src/components/MyCustomCardComponent.astro
    ---
    import type { ImageMetadata } from 'astro';
    import { Image } from 'astro:assets';
    interface Props {
    imagePath: string;
    altText: string;
    name: string;
    age: number;
    }
    const { imagePath, altText, name, age } = Astro.props;
    const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}')
    ---
  5. 使用 props 属性来为你的组件创建 HTML 标记。

    src/components/MyCustomCardComponent.astro
    ---
    import type { ImageMetadata } from 'astro';
    import { Image } from 'astro:assets';
    interface Props {
    imagePath: string;
    altText: string;
    name: string;
    age: number;
    }
    const { imagePath, altText, name, age } = Astro.props;
    const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}');
    ---
    <div class="card">
    <h2>{name}</h2>
    <p>Age: {age}</p>
    <Image src={} alt={altText} />
    </div>
  6. src 属性中,传入 images 对象并使用方括号表示法来指定图片路径。然后确保调用 glob 函数。

    由于你正在访问的 images 对象类型未知,所以你也应该在传递了无效文件路径作为 prop 时 throw 一个错误。

    src/components/MyCustomCardComponent.astro
    ---
    import type { ImageMetadata } from 'astro';
    import { Image } from 'astro:assets';
    interface Props {
    imagePath: string;
    altText: string;
    name: string;
    age: number;
    }
    const { imagePath, altText, name, age } = Astro.props;
    const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}');
    if (!images[imagePath]) throw new Error(`"${imagePath}" does not exist in glob: "src/assets/*.{jpeg,jpg,png,gif}"`);
    ---
    <div class="card">
    <h2>{name}</h2>
    <p>Age: {age}</p>
    <Image src={images[imagePath]()} alt={altText} />
    </div>
  7. 在一个 Astro 页面中导入并使用卡片组件,并传入 props 的值。

    src/pages/index.astro
    ---
    import MyCustomCardComponent from '../components/MyCustomCardComponent.astro';
    ---
    <MyCustomCardComponent
    imagePath="/src/assets/avatar-1.jpg"
    altText="A headshot of Priya against a brick wall background."
    name="Priya"
    age={25}
    />