在 Gatsby 中,如何将相对路径文件传递给同时拉取查询的模板?

Posted

技术标签:

【中文标题】在 Gatsby 中,如何将相对路径文件传递给同时拉取查询的模板?【英文标题】:In Gatsby how do I pass a relative path file to a template that is also pulling a query? 【发布时间】:2021-05-15 18:56:25 【问题描述】:

在 Gatsby 中,我编写了一个帖子模板:

singlePost.js:

import React from 'react'
import  graphql  from 'gatsby'
import  MDXRenderer  from 'gatsby-plugin-mdx'
import  H1  from '../elements'
import  Container, Post, FeatureImage  from '../components'
const singlePost = ( data ) => 
  const featureImage = data.mdx.frontmatter.featureImg.childImageSharp.fixed
  return (
    <Container>
      <FeatureImage fixed=featureImage />
      <Post>
        <H1 margin=" 0 0 2rem 0">data.mdx.frontmatter.title</H1>
        <MDXRenderer>data.mdx.body</MDXRenderer>
      </Post>
    </Container>
  )

export const pageQuery = graphql`
  query SinglePostQuery($id: String!) 
    mdx(id:  eq: $id ) 
      body
      frontmatter 
        date
        excerpt
        featureImg 
          childImageSharp 
            fixed(width: 1920) 
              ...GatsbyImageSharpFixed
            
          
        
        title
        slug
      
    
  
`
export default singlePost

在我的 gatsby-node.js 中,我从 slug 中获取数据:

 data.allMdx.edges.map(edge => 
    const slug = edge.node.frontmatter.slug
    const id = edge.node.id
    actions.createPage(
      path: slug,
      component: require.resolve(`./src/templates/singlePost.js`),
      context:  id ,
    )
  )

在markdown文件的frontmatter中有一张特征图:

---
title: Bacon Ipsum
slug: bacon
date: 2021-02-09
featureImg: nature.jpg
excerpt: Bacon ipsum dolor amet pastrami prosciutto meatball fatback, andouille drumstick shank burgdoggen brisket cow turkey.
---

如果 post markdown 文件没有图像,我会收到以下错误:

无法读取 null 的属性“childImageSharp”

我可以访问我设置的默认图像:

const defaultImage = useStaticQuery(graphql`
  query 
    default: file(relativePath:  eq: "default.jpg" ) 
      publicURL
    
  
`)

但是当我尝试查询内容和默认值时:

const defaultImage = useStaticQuery(graphql`
  query SinglePostQuery($id: String!) 
    mdx(id:  eq: $id ) 
      body
      frontmatter 
        date
        excerpt
        featureImg 
          childImageSharp 
            fixed(width: 1920) 
              ...GatsbyImageSharpFixed
            
          
        
        title
        slug
      
    
    default: file(relativePath:  eq: "default.jpg" ) 
      publicURL
    
  
`)

我收到以下错误:

如果您使用的不是页面查询,而是 useStaticQuery / StaticQuery 您会看到此错误,因为它们目前不支持变量。

在 Gatsby 中,我如何查询 slug,同时将默认图像传递给 Feature Image 组件?

【问题讨论】:

【参考方案1】:

正如错误日志所指出的,useStaticQuery(因为它是一种静态查询)不接受变量,因此得名。

在 Gatsby 中,我如何查询 slug 并通过默认值 图像到特征图像组件?

在使用页面查询时,您可以使用附加 id 的相同上下文来传递图像。

  data.allMdx.edges.map(edge => 
        const slug = edge.node.frontmatter.slug
        const id = edge.node.id
        const imagePath = edge.node.featureImg || 'default.jpg'
        actions.createPage(
          path: slug,
          component: require.resolve(`./src/templates/singlePost.js`),
          context:  
            id 
            imagePath
           ,
        )
      )

注意:您可能需要在gatsby-node.js 中查询图像。如果需要,将imagePath 更改为与您的数据结构更匹配的另一个标识符。

然后,在您的模板中:

import React from 'react'
import  graphql  from 'gatsby'
import  MDXRenderer  from 'gatsby-plugin-mdx'
import  H1  from '../elements'
import  Container, Post, FeatureImage  from '../components'
const singlePost = ( data ) => 
  const featureImage = data.mdx.frontmatter.featureImg.childImageSharp.fixed
  return (
    <Container>
      <FeatureImage fixed=featureImage />
      <Post>
        <H1 margin=" 0 0 2rem 0">data.mdx.frontmatter.title</H1>
        <MDXRenderer>data.mdx.body</MDXRenderer>
      </Post>
    </Container>
  )

export const pageQuery = graphql`
  query SinglePostQuery($id: String!, $imagePath: String) 
    mdx(id:  eq: $id ) 
      body
      frontmatter 
        date
        excerpt
        featureImg 
          childImageSharp 
            fixed(width: 1920) 
              ...GatsbyImageSharpFixed
            
          
        
        title
        slug
      
    
    default: file(relativePath:  eq: $imagePath ) 
      publicURL
    
  
`
export default singlePost

注意:将$imagePath 添加为可空值(通过删除感叹号!),因为正如您所说,并非所有帖子都会包含它。

如果featureImg 块仍然中断查询,请尝试删除它。因为:

const imagePath = edge.node.featureImg || 'default.jpg'

您的imagePath 变量将始终包含所需的数据,或者您的featureImg,或者您的默认数据。关键是进行单独的查询。

【讨论】:

以上是关于在 Gatsby 中,如何将相对路径文件传递给同时拉取查询的模板?的主要内容,如果未能解决你的问题,请参考以下文章

将相对路径作为属性文件中的属性

如何将相对路径转换为 ​​C#/.NET 中的完全限定路径?

aspcms怎么将相对路径改成绝对路径

Gatsby:如何将多个上下文 ID 传递给单个查询?

如何在 NodeJS 中使用相对路径(参数)获取文件

将相对路径转换为绝对路径?