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



所以我有一个可以渲染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

有没有一种方法可以动态添加图像,然后将其呈现到新页面?

像这样的<Image src={"profile.jpg"} />

我不知道如何将其添加到graphql中,并假设我有50个图像,然后我必须映射所有50个图像或手动添加每个查询,这没有意义

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

您总是可以使用graphql片段,并为您的查询编写如下内容,然后根据通过图像组件中的道具传递的文件名有条件地渲染正确的图像,但遗憾的是,这也相当笨拙:

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} />

正如Apena的回答所解释的,像这样处理盖茨比的图像是很棘手的。但是,我必须指出,根据使用的文件系统和数据的结构,您可以以不同的方式绕过它。

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

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和页面查询之间的区别,以了解哪种查询适合您以及它们的局限性。

如果你使用一个页面查询,你总是可以创建一个像下面这样的方法:

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图像。

最新更新