【问题标题】:How do I query multiple images with gatsby-image?如何使用 gatsby-image 查询多个图像?
【发布时间】:2019-10-19 14:09:13
【问题描述】:

我有 16 张图像要以网格格式呈现到网站上。

我为此使用了以下插件:

  • gatsby-image
  • gatsby-source-filesystem
  • gatsby-plugin-sharp
  • gatsby-transformer-sharp

我阅读了文档,据我所知,它只演示了如何查询单个图像。

例如

import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"

export default ({ data }) => (
  <div>
    <h1>Hello gatsby-image</h1>
    <Img fixed={data.file.childImageSharp.fixed} />
  </div>
)

export const query = graphql`
  query {
    file(relativePath: { eq: "blog/avatars/kyle-mathews.jpeg" }) {
      childImageSharp {
        # Specify the image processing specifications right in the query.
        # Makes it trivial to update as your page's design changes.
        fixed(width: 125, height: 125) {
          ...GatsbyImageSharpFixed
        }
      }
    }
  }
`

但是,如果我有 16 张图片,我该怎么做呢?编写 16 个单独的查询似乎相当麻烦,并且将来难以阅读。

我在引用多张图片的文档中看到了这段代码,但我在尝试访问这些图片时遇到了麻烦。

例如

export const squareImage = graphql`
  fragment squareImage on File {
    childImageSharp {
      fluid(maxWidth: 200, maxHeight: 200) {
        ...GatsbyImageSharpFluid
      }
    }
  }
`

export const query = graphql`
  query {
    image1: file(relativePath: { eq: "images/image1.jpg" }) {
      ...squareImage
    }

    image2: file(relativePath: { eq: "images/image2.jpg" }) {
      ...squareImage
    }

    image3: file(relativePath: { eq: "images/image3.jpg" }) {
      ...squareImage
    }
  }
`

我的文件夹结构如下:

---package.json

---src

-----图片

--------- 16 张图片

------页面

---------我要在其中渲染16张图片的页面

等等

谢谢。

【问题讨论】:

  • 提供的答案没有解释如何使用示例中给出的代码。我还没有弄清楚如何导入image1、image2和image3。任何帮助将不胜感激。
  • Hi @R3N0、“image1:”、“image2:”等是别名,因此您可以将它们称为data.image1.childImageSharp... 等。

标签: reactjs gatsby


【解决方案1】:

了解一下 GraphiQL 应该会对您有所帮助,尤其是 Explorer。尽管请记住 Gatsby 片段在 GraphiQL 中不起作用。

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

所以上面应该等于下面的查询,在 GraphiQL 中工作

{
  allImageSharp {
    edges {
      node {
        id
        fluid(maxHeight: 200, maxWidth: 200) {
          src
          srcSet
          base64
          aspectRatio
          originalImg
          sizes        
        }
      }
    }
  }
}

然后您的组件可以使用相同的查询并呈现如下结果:

import React from "react"
import { graphql } from "gatsby"
import Img from "gatsby-image"

const imgGridStyle = {
  display: 'grid',
  gridTemplateColumns: `repeat(auto-fill, 200px)`
};

export default ({ data }) => (
  <div>
    <h1>Hello gatsby-image</h1>
    <div style={imgGridStyle}>
      {data.allImageSharp.edges.map(edge => 
        <Img fluid={edge.node.fluid} />
      )}
    </div>
  </div>
)

export const query = graphql`
  query {
    allImageSharp {
      edges {
        node {
          id
          fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  }
`

您可以轻松地遍历从data.allImageSharp.edges.map 中的查询返回的 imageSharp 节点的结果数组。然后将每个节点的fluid 属性作为fluid 属性传递给gatsby-image

注意:这会渲染您项目中的每个 imageSharp 节点,这可能是您想要实现的,也可能不是。


要按文件夹名称过滤查询,您可以像这样调整查询:

{
  allImageSharp(filter: {fileAbsolutePath: {regex: "/(myFolder)/"  }}) {
    edges {
      node {
        id
        fluid(maxWidth: 200, maxHeight: 200) {
            ...GatsbyImageSharpFluid
        }
      }
    }
  }
}

查看gatsby graphql reference for filter,了解如何对查询执行其他类型的过滤器。

【讨论】:

  • 漂亮的解决方案,完美运行!谢谢你。我想问一个跟进。由于流体图像会自动填充容器的宽度,我如何确保maxWidth 适用于流体图像,以便当它的宽度小于其容器时,保持宽度。
  • 我对网格容器的 css 做了一个小的编辑。但基本上,您只需要 css 以某种方式将每个 &lt;Img /&gt; 限制为最大宽度为 200 像素。在 CSS 中有很多方法可以做到这一点(但它们可能超出了这个问题的范围),所以请随时提出另一个问题并将我链接到这里。
  • 太棒了,你是对的。添加与查询样式匹配的其他 CSS 样式有效。谢谢你。似乎即使不使用CSS Gridgatsby-image 已经有flex-wrap 用于响应式设计?我用固定图像对其进行了测试。
  • 使用此解决方案,如何指定包含图像的文件夹的路径?例如,对于单个图像,image1: file(relativePath: { eq: "images/image1.jpg" })
  • 很好的解决方案,在stackoverflow.com/questions/66405411/…解决了我的问题
【解决方案2】:

从 Gatsby v3 开始,您只需要使用 gatsby-plugin-image 插件,它提供自动图像优化

import { StaticImage } from "gatsby-plugin-image"
export function Dino() {
  return (
    <StaticImage
      src="../images/dino.png"
      alt="A dinosaur"
      placeholder="blurred"
      layout="fixed"
      width={200}
      height={200}
    />
  )
}

更多信息: https://www.gatsbyjs.com/docs/how-to/images-and-media/using-gatsby-plugin-image

盖茨比 v2:

最简单的方法是创建图片提供者:

import React from 'react'
import { graphql, useStaticQuery } from 'gatsby'
import Img from 'gatsby-image'

const Image = ({ fileName, alt, style }) => {
  const { allImageSharp } = useStaticQuery(graphql`
    query {
      allImageSharp {
        nodes {
          fluid(maxWidth: 1600) {
            originalName
            ...GatsbyImageSharpFluid_withWebp
          }
        }
      }
    }
  `)

  const fluid = allImageSharp.nodes.find(n => n.fluid.originalName === fileName)
    .fluid

  return (
    <figure>
      <Img fluid={fluid} alt={alt} style={style} />
    </figure>
  )
}

export default Image;

然后,导入后,轻松插入你需要的图片:

<Image fileName="yourImage.jpg" style={{ width: '100%' }} alt="" />

【讨论】:

  • 它可以工作,但是捆绑包大小......我们能以某种方式改进它吗?我知道静态查询中不允许出现像 ${name} 这样的争论。
  • 我们有什么替代方法可以在 graghql 查询中使用变量进行查询
【解决方案3】:

下面是一个支持 TypeScript 和 SVG 的简单示例:

更新 gatsby-config.js

module.exports = {
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/assets/images`,
      },
    },
  ],
};

创建图片组件

import * as React from 'react';
import { FC } from 'react';
import { graphql, StaticQuery } from 'gatsby';
import Img from 'gatsby-image';

interface IProps {
  name: string;
  alt: string;
  className?: string;
}

const Image: FC<IProps> = ({ name, alt, className }) => (
  <StaticQuery
    query={graphql`
      query AllImages {
        allImagesWithoutSVGExtension: allFile(
          filter: {
            sourceInstanceName: { eq: "images" }
            extension: { regex: "/jpeg|jpg|png|gif/" }
          }
        ) {
          nodes {
            publicURL
            extension
            sharp: childImageSharp {
              fluid {
                originalName
                ...GatsbyImageSharpFluid_withWebp
              }
            }
          }
        }
        allImagesWithSVGExtension: allFile(
          filter: {
            sourceInstanceName: { eq: "images" }
            extension: { eq: "svg" }
          }
        ) {
          nodes {
            publicURL
            extension
          }
        }
      }
    `}
    render={({ allImagesWithoutSVGExtension, allImagesWithSVGExtension }) => {
      const isNameWithSVGExtension = name.indexOf('svg') !== -1;

      const renderImageWithSVGExtension = () => {
        const image = allImagesWithSVGExtension.nodes.find(
          ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
        );
        return image ? (
          <img
            className={className}
            src={image.publicURL}
            alt={alt}
            width={100}
            height={100}
          />
        ) : null;
      };

      const renderImageWithoutSVGExtension = () => {
        const image = allImagesWithoutSVGExtension.nodes.find(
          ({ publicURL }) => publicURL && publicURL.indexOf(name) !== -1
        );
        return image && image.sharp && image.sharp.fluid ? (
          <Img className={className} fluid={image.sharp.fluid} alt={alt} />
        ) : null;
      };

      return isNameWithSVGExtension
        ? renderImageWithSVGExtension()
        : renderImageWithoutSVGExtension();
    }}
  />
);

export { Image };

使用图片组件作为

<Image name="logo.svg" alt="compony logo" />
or
<Image name="logo.png" alt="compony logo" />

【讨论】:

    【解决方案4】:

    尽管在当前提出的问题中存在这种情况,所有 16 幅图像都在图像文件夹中,然后很容易运行查询以获取所有可能的图像。像这样(接受的答案):

    {
      allImageSharp {
        edges {
          node {
            id
            fluid(maxWidth: 200, maxHeight: 200) {
                ...GatsbyImageSharpFluid
            }
          }
        }
      }
    }
    

    但在大多数情况下,您希望在图像文件夹中包含子文件夹,以便根据需要排列图像。 (至少我的情况是这样)。

    所以在这种情况下:(如果您在子文件夹中有图像,比如说 beachimages 中,您可以采用这种方法)

    export const query = graphql`
      query {
        allFile(filter: { relativeDirectory: { eq: "beach" } }) {
          edges {
            node {
              id
              childImageSharp {
                fluid {
                  ...GatsbyImageSharpFluid_withWebp
                }
              }
            }
          }
        }
      }
    `
    

    如果你想在视频中看到,这是一个小egghead clip

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 2021-06-05
      • 2020-06-09
      • 2018-06-16
      • 2021-05-29
      • 2020-09-27
      • 2020-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多