如何使用图像组件将图像动态添加到 Gatsby 中的页面?

Posted

技术标签:

【中文标题】如何使用图像组件将图像动态添加到 Gatsby 中的页面?【英文标题】:How can I dynamically add images to my pages in Gatsby using the image component? 【发布时间】:2021-01-02 20:40:50 【问题描述】:

所以我有渲染 2 个不同图像的图像组件,但我希望能够将我的图像组件添加到任何页面,并将特定图像作为道具传递,而不必硬编码新的查询我需要使用的每张图片。

如果我有 50 张图片,我只想将 image-50.jpg 作为道具传入,而不是对其进行特定查询。有没有办法在 gatsby 中使用 graphql 来做到这一点?

这是我目前的图片组件代码

      import  graphql, useStaticQuery  from "gatsby"
      import Img from "gatsby-image"
      import React from "react"

      const Image = () => 
        const data = useStaticQuery(graphql`
          query 
            astronaut: file(relativePath:  eq: "gatsby-astronaut.png" ) 
              childImageSharp 
                fluid(maxHeight: 600) 
                  ...GatsbyImageSharpFluid
                
              
            
            person: file(relativePath:  eq: "profile.jpg" ) 
              childImageSharp 
                fluid(maxHeight: 600) 
                  ...GatsbyImageSharpFluid
                
              
            
          
        `)

        return (
          <>
            <Img fluid=data.astronaut.childImageSharp.fluid />
            <Img fluid=data.person.childImageSharp.fluid />
          </>
        )
      

      export default Image

有没有办法只动态添加图像,然后将其渲染到新页面?

类似 &lt;Image src="profile.jpg" /&gt;

我不知道如何将它添加到 graphql 并想象我有 50 张图片,然后我必须映射所有 50 张图片或手动添加每个查询,这没有意义

【问题讨论】:

这能回答你的问题吗? Reusable Gatsby-Image Component with dynamic image sources 【参考方案1】:

信不信由你,您无法使用gastby-image 创建一个完全动态的图像组件,而不会冒着包大小(可能非常大)膨胀的风险。问题是 Gatsby 中的静态查询不支持其模板文字中的字符串插值。每次使用该组件时,您都需要搜索所有文件。 您可以在 here 找到的现有 SO 帖子中尝试一些解决方案。

您始终可以使用 graphql 片段并为您的查询编写如下所示的内容,然后根据通过 Image 组件中的 props 传递的文件名有条件地渲染正确的图像,但这也很笨拙:

export const fluidImage = graphql`
fragment fluidImage on File 
  childImageSharp 
    fluid(maxWidth: 1000) 
      ...GatsbyImageSharpFluid
    
  

`;

export const data = graphql`
  query 
    imageOne: file(relativePath:  eq: "one.jpg" ) 
      ...fluidImage
    
    imageTwo: file(relativePath:  eq: "two.jpg" ) 
      ...fluidImage
    
    imageThree: file(relativePath:  eq: "three.jpg" ) 
      ...fluidImage
    
  
`
// accessed like this
<Img fluid=data.imageOne.childImageSharp.fluid />
// or this
<Img fluid=data.imageTwo.childImageSharp.fluid />
// or this, dynamically (if you had a prop called imageName)
<Img fluid=data.[`$props.imageName`].childImageSharp.fluid />

【讨论】:

【参考方案2】:

正如Apena's answer 解释的那样,像 Gatsby's Image 那样工作是很棘手的。但是,我必须说,您可以根据使用的文件系统和数据的结构以不同的方式绕过它。

请记住,如果您在 gatsby-config.js 中正确设置了文件系统,您将允许 Gatsby 识别并找到您项目中的所有图像,使它们可查询并允许 Gatsby Image 组件使用它们。

const path = require(`path`)

module.exports = 
  plugins: [
    
      resolve: `gatsby-source-filesystem`,
      options: 
        name: `images`,
        path: path.join(__dirname, `src`, `images`),
      ,
    ,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
  ],

您可以找到比在路径过滤的staticQuery 中查询每个图像更好的方法,这不是实现它的唯一方法。当然,如果您使用staticQuery 方法,使其动态化的限制会迫使您分别进行每个查询。

首先,您需要了解staticQuery and page query 之间的区别,以了解哪个适合您以及它们的局限性。

如果您使用页面查询,您始终可以创建类似以下的方法:

import React from 'react'
import  graphql  from 'gatsby'
import Layout from '../components/layout'

class ProductPage extends React.Component 
  render() 

    const products = get(this, 'props.data.allDataJson.edges')

    return (
      <Layout>
        products.map(( node ) => 
          return (
            <div key=node.name>
              <p>node.name</p>
              <Img fluid=node.image.childImageSharp.fluid />
            </div>
          )
        )
      </Layout>
    )
  


export default ProductPage


export const productsQuery = graphql`
  query 
    allDataJson 
      edges 
        node 
          slug
          name
          image
            publicURL
            childImageSharp
              fluid 
                ...GatsbyImageSharpFluid
              
            
          
        
      
    
  
`

在上面的示例中,您使用页面查询从 JSON 文件中检索所有图像。如果您在文件系统中设置路径,您将能够使用 GraphQL 片段检索它们。这种方式在处理 Gatsby Image 时更能承受动态,最好是逐个查询。

其他文件系统的想法保持不变,这只是一种适应性强的方法。如果您使用像 Contentful 这样的 CMS,您可以下载资产并以相同的方式动态查询它们,因为文件系统允许您这样做。

页面查询只允许在页面组件中使用(因此得名),因此,如果您想在 React 独立组件中使用它以使其可重用,您需要通过 props(或 reducer)传递给您想要的组件和根据接收到的 props 渲染 Gatsby 图片。

【讨论】:

以上是关于如何使用图像组件将图像动态添加到 Gatsby 中的页面?的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量添加到 GraphQL 文件查询

如何在 Gatsby 中为我的可重用组件返回特定图像?

gatsby-image:如何将处理后的图像导入 css 并与 background-image 属性一起使用

使用 GraphQL 映射 Gatsby 画廊图像

如何在内容丰富的 Gatsby 中包含轮播组件?

如何改进对特定图像的 gatsby 图像查询