javascript 从Astro中的文件夹动态导入所有图像

ndasle7k  于 2023-03-21  发布在  Java
关注(0)|答案(2)|浏览(186)

我正在使用Astro。该项目使用了相当多的图像,我想简化我目前添加新图像的方式。我的路由如下:

example.com/pictures/[collection]

(“[”和“]”代表动态路由)
允许例如:
example.com/pictures/mixed-tecnique
example.com/pictures/graphite
example.com/pictures/acrylic
pages/pictures/[collection].astro文件中,我想做以下事情(或类似的事情):

---
import * as collections from "public/img/collections"

const { collection } = Astro.props
---

{collections[collection].map(imgSrc => <img src={imgSrc} />)}

所以现在,要有一个新的收藏路径,我只需要创建一个新的文件夹并将图像放在那里。
有什么办法可以达到同样的结果吗?提前感谢!!

5uzkadbs

5uzkadbs1#

有很多不同的方法来实现这样的特性,但这里有一个使用fast-glob库的简单示例

public
  pictures
    mixed-technique
      example.png
      example.png
      example.png
    graphite
      example.png
      example.png
      example.png
    arcylic
      example.png
      example.png
      example.png
// src/pages/pictures/[collection].astro
---
import fg from 'fast-glob';

export async function getStaticPaths() {
    // get all collection folder paths: 'public/pictures/[collection]'
    const collections: string[] = fg.sync('public/pictures/*', { onlyDirectories: true })

    // Create a new route for every collection
    return collections.map(collection => {

        // Create Route
        return {
            params: {
                // Return folder name of collection as dynamic parameter [collection]
                collection: collection.split('/').pop()
            },
            props: {
                // Return array of all image srcs in collection as prop 'images'
                images: fg.sync(`${collection}/**/*.{png,jpg}`).map(img => img.replace('public/', '/'))
            }
        }
    })
}

export interface Props {
    images: string[];
}

const { collection } = Astro.params

const { images } = Astro.props
---

<html lang="en">
    <head>
        <!-- ... -->
    </head>
    <body>
        { images.map(img => <img src={img}/>) }
    </body>
</html>

注意:我使用了fast-glob而不是Astro.globimport.meta.glob(),因为它可以将变量作为参数(使此逻辑更容易/更具动态性),并且因为它只返回文件/文件夹路径的数组,而不是同时尝试返回文件内容

7vux5j2d

7vux5j2d2#

这就是我如何做到的:

---
const images = await Astro.glob("/src/assets/img/salon/*").then(files => {
  return files.map(file => file.default);
});
---

<div class="swiper">
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->
    {
      images.map(image => (
        <div class="flex items-center justify-center swiper-slide">
          <img
            class="object-contain h-full rounded-lg"
            src={image}
            alt=""
            loading="lazy"
          />
        </div>
      ))
    }
  </div>
  ...
</div>

如果您使用的是experimental assets feature

{
  images.map(({ src /* width and height is also available */ }) => (
    <div class="flex items-center justify-center swiper-slide">
      <img
        class="object-contain h-full rounded-lg"
        src={src}
        alt=""
        loading="lazy"
      />
    </div>
  ))
}

相关问题