使用 Gatsby.js 搭建靜態博客 2 實現分頁

原文地址:https://ssshooter.com/2018-12...

可以先複習 -> 使用 Gatsby.js 搭建靜態博客 1 關鍵文件 <-

本文將會介紹如何爲初始項目添加分頁功能。

理解頁面創建原理

上一篇的 gatsby-node.js 介紹部分已經說明了頁面生成的方法。

未修改前,首頁 index.js 存在於 pages 文件夾,不需要在 gatsby-node.js 使用 createPage 函數生成,因爲 createPage 多用於遍歷數據批量生成頁面。

而我們現在的需求就正好需要用到!文章的分頁需要把文章列表分割爲每頁 N 篇文章的,M 個頁面,因此需要使用 createPage

添加分頁模板

首先在 templates 文件夾創建 index.js(或者 blog.js,你喜歡)。

文件內容大部分都跟現有的 index.js 一樣,但是有以下改動:

添加翻頁按鈕

// 數據來源是 createPage 注入的上下文變量
const { totalPage, currentPage } = this.props.pageContext

······

<div>
  {currentPage - 1 > 0 && (
    <Link
      to={'/blog/' + (currentPage - 1 === 1 ? '' : currentPage - 1)}
      rel="prev"
    >
      ← 上一頁
    </Link>
  )}
</div>
<div>
  {currentPage + 1 <= totalPage && (
    <Link to={'/blog/' + (currentPage + 1)} rel="next">
      下一頁 →
    </Link>
  )}
</div>

在查詢中添加分頁邏輯

// $skip 和 $limit 的來源也是 context
// 不過可以注意到在查詢中這些變量就存在於最外層而不需要訪問對象屬性獲取
export const pageQuery = graphql`
  query($skip: Int!, $limit: Int!) {
    site {
      siteMetadata {
        title
        description
      }
    }
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          excerpt
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
          }
        }
      }
    }
  }
`

gatsby-node.js 修改生成函數

這裏是批量生成分頁頁面的邏輯,根據每頁文章數 postsPerPage 計算生成頁面總數,然後向每頁注入四個變量,包括:

  • 當前頁數
  • 總頁數
  • 每次獲取數據的數量
  • 跳過前面數據的數量

模板頁面有了這些參數便可以方便查詢出該頁面需要渲染什麼文章。

//  create homepage pagination
const postsPerPage = 8
const numPages = Math.ceil(posts.length / postsPerPage)

Array.from({ length: numPages }).forEach((_, i) => {
  createPage({
    path: i === 0 ? `/blog` : `/blog/${i + 1}`,
    component: homePaginate,
    context: {
      currentPage: i+1,
      totalPage:numPages,
      limit: postsPerPage,
      skip: i * postsPerPage,
    },
  })
})

功能實現了,但是這裏有一個突發事件:

原來的頁面是這樣的:

我什麼都沒修改怎麼就變成這樣了?

註釋了 <bio /> 發現這塊不屬於 title,而 helmet 是用於處理 html 元數據,懵逼了一段時間,終於明白是 layout 組件的問題.

layout 組件裏面寫法是在根目錄的時候把 title 放大,但是添加分頁之後,主頁路由從根目錄 / 變爲 /blog,於是產生了這個詭異的問題。

不過由於本來就打算重寫樣式,這一塊可以放心刪掉!

處理完這個問題你的新博客就實現分頁功能了!下一步是樣式的相關調整,留到下一篇繼續講


path: "/gatsby-blog-2"
date: "2018-12-10T21:16:11.388Z"
title: "使用 Gatsby.js 搭建靜態博客 2 實現分頁"

tags: ["coding"]

可以先複習 -> 使用 Gatsby.js 搭建靜態博客 1 關鍵文件 <-

本文將會介紹如何爲初始項目添加分頁功能。

理解頁面創建原理

上一篇的 gatsby-node.js 介紹部分已經說明了頁面生成的方法。

未修改前,首頁 index.js 存在於 pages 文件夾,不需要在 gatsby-node.js 使用 createPage 函數生成,因爲 createPage 多用於遍歷數據批量生成頁面。

而我們現在的需求就正好需要用到!文章的分頁需要把文章列表分割爲每頁 N 篇文章的,M 個頁面,因此需要使用 createPage

添加分頁模板

首先在 templates 文件夾創建 index.js(或者 blog.js,你喜歡)。

文件內容大部分都跟現有的 index.js 一樣,但是有以下改動:

添加翻頁按鈕

// 數據來源是 createPage 注入的上下文變量
const { totalPage, currentPage } = this.props.pageContext

······

<div>
  {currentPage - 1 > 0 && (
    <Link
      to={'/blog/' + (currentPage - 1 === 1 ? '' : currentPage - 1)}
      rel="prev"
    >
      ← 上一頁
    </Link>
  )}
</div>
<div>
  {currentPage + 1 <= totalPage && (
    <Link to={'/blog/' + (currentPage + 1)} rel="next">
      下一頁 →
    </Link>
  )}
</div>

在查詢中添加分頁邏輯

// $skip 和 $limit 的來源也是 context
// 不過可以注意到在查詢中這些變量就存在於最外層而不需要訪問對象屬性獲取
export const pageQuery = graphql`
  query($skip: Int!, $limit: Int!) {
    site {
      siteMetadata {
        title
        description
      }
    }
    allMarkdownRemark(
      sort: { fields: [frontmatter___date], order: DESC }
      limit: $limit
      skip: $skip
    ) {
      edges {
        node {
          excerpt
          fields {
            slug
          }
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
          }
        }
      }
    }
  }
`

gatsby-node.js 修改生成函數

這裏是批量生成分頁頁面的邏輯,根據每頁文章數 postsPerPage 計算生成頁面總數,然後向每頁注入四個變量,包括:

  • 當前頁數
  • 總頁數
  • 每次獲取數據的數量
  • 跳過前面數據的數量

模板頁面有了這些參數便可以方便查詢出該頁面需要渲染什麼文章。

//  create homepage pagination
const postsPerPage = 8
const numPages = Math.ceil(posts.length / postsPerPage)

Array.from({ length: numPages }).forEach((_, i) => {
  createPage({
    path: i === 0 ? `/blog` : `/blog/${i + 1}`,
    component: homePaginate,
    context: {
      currentPage: i+1,
      totalPage:numPages,
      limit: postsPerPage,
      skip: i * postsPerPage,
    },
  })
})

功能實現了,但是這裏有一個突發事件:

原來的頁面是這樣的:

我什麼都沒修改怎麼就變成這樣了?

註釋了 <bio /> 發現這塊不屬於 title,而 helmet 是用於處理 html 元數據,懵逼了一段時間,終於明白是 layout 組件的問題.

layout 組件裏面寫法是在根目錄的時候把 title 放大,但是添加分頁之後,主頁路由從根目錄 / 變爲 /blog,於是產生了這個詭異的問題。

不過由於本來就打算重寫樣式,這一塊可以放心刪掉!

處理完這個問題你的新博客就實現分頁功能了!下一步是樣式的相關調整,留到下一篇繼續講

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章