在 Gatsby 中使用 GraphQL 获取许多图像时如何保持 DRY
Posted
技术标签:
【中文标题】在 Gatsby 中使用 GraphQL 获取许多图像时如何保持 DRY【英文标题】:How to keep DRY when fetching many images using GraphQL in Gatsby 【发布时间】:2018-09-02 17:38:38 【问题描述】:假设我想在一篇关于 Gatsby 的博客文章中包含 50 张图片。使用 GraphQL 获取图像。我最终为 50 张图片中的每一张都编写了非常重复的查询,如下所示:
export const query = graphql`
query ArticleImageQuery
coverImage: imageSharp(id: regex: "/cover-image/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
artisan1: imageSharp(id: regex: "/artisan1/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
artisan2: imageSharp(id: regex: "/artisan2/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
artisan3: imageSharp(id: regex: "/artisan3/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
johannystrom1: imageSharp(id: regex: "/johan-nystrom1/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
johannystrom2: imageSharp(id: regex: "/johan-nystrom2/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
johannystrom3: imageSharp(id: regex: "/johan-nystrom3/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
johannystrom4: imageSharp(id: regex: "/johan-nystrom4/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
fratello1: imageSharp(id: regex: "/fratello/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
booksAntiques1: imageSharp(id: regex: "/books-antiques1/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
booksAntiques2: imageSharp(id: regex: "/books-antiques2/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
pastor1: imageSharp(id: regex: "/pastor1/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
pastor2: imageSharp(id: regex: "/pastor2/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
pastor3: imageSharp(id: regex: "/pastor3/" )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
libertyOrDeath1: imageSharp(id: regex: "/liberty-death1/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
libertyOrDeath2: imageSharp(id: regex: "/liberty-death2/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
kaisla1: imageSharp(id: regex: "/kaisla1/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
blockDylan1: imageSharp(id: regex: "/block-dylan1/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
blockDylan2: imageSharp(id: regex: "/block-dylan2/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
blockDylan3: imageSharp(id: regex: "/block-dylan3/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
blockDylan4: imageSharp(id: regex: "/block-dylan4/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
blockDylan5: imageSharp(id: regex: "/block-dylan5/" )
sizes(maxWidth: 700, maxHeight: 525, cropFocus: CENTER)
...GatsbyImageSharpSizes
,
/* The list goes on, you get the idea... */
`;
这严重违反了 DRY(不要重复自己)原则。我试图摆弄片段,但我是一个 GraphQL 菜鸟用户,我只是不知道如何重用这个重复的代码并只写一次,而不是 50 次?
我可以做些什么来改善这一点?
理想情况下,我希望有一个代码,我可以在其中编写一次重复部分,然后将其重复用于我获取的每个图像。例如:
/* NOTE: FICTIONAL PSEUDOCODE */
const imageQuery = graphql`
query ImageQuery($path: String!)
imageSharp(id: regex: $path )
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
,
`;
export const query = graphql`
query ArticleImageQuery
coverImage: ImageQuery("/cover-image/"),
artisan1: ImageQuery("/artisan1/"),
artisan2: ImageQuery("/artisan2/"),
artisan3: ImageQuery("/artisan3/"),
johannystrom1: ImageQuery("/johan-nystrom1/"),'
/* ... AND SO ON */
`;
【问题讨论】:
【参考方案1】:GraphQL 片段没有参数。请参阅this github issue 了解更多信息。
当我遇到与您类似的问题时,我会通过一次查询选择我需要的所有图像,然后在视图中处理它们。例如这样的查询:
export const query = graphql`
allFile(filter: absolutePath: regex: "/img/o-meni/im/")
edges
node
id
name
publicURL
childImageSharp
sizes(maxWidth: 700, maxHeight: 525)
...GatsbyImageSharpSizes
`
然后您可以过滤特定图像,例如 artisan1
或 React 组件中的任何一个。要显示它们,您可以使用如下代码:
this.props.data.allFile.edges.map(( node ) =>
<a href=node.publicURL key=node.id>
<Img sizes=node.childImageSharp.sizes alt=node.name title=node.name />
</a>
)
【讨论】:
以上是关于在 Gatsby 中使用 GraphQL 获取许多图像时如何保持 DRY的主要内容,如果未能解决你的问题,请参考以下文章
使用 Gatsby/Contentful 从 Graphql 获取参考数据
如果在 Gatsby 中布尔键匹配 true,则从对象内的对象数组中获取项目 - Graphql
gatsby 无法获取所有关于 vercel 生产的 graphql 数据