原文連結:https://ssshooter.com/2019-01...
前面說過基本功能已經新增完了,但是生成目錄依然是我 TODO 的頭號問題。今天終於把這個問題解決了,本來以為要自己解釋 md 檔案,沒想到自帶的外掛就有這個功能我卻沒發現。
生成目錄
獲取目錄資料
生成目錄首先要獲取目錄資料,此功能由外掛 gatsby-transformer-remark
提供,請務必先安裝。
安裝後在你需要獲取目錄的頁面的 graphQL 查詢程式碼中新增 tableOfContents
。tableOfContents
後面的 pathToSlugField 用於生成錨點連結地址,預設值為當前文章的 slug
。在例子中就把地址的字首改成 md 檔案提供的 path 了。這個位置就看你本來的地址怎麼配置,如果本來就是 slug 則不用修改,直接寫 tableOfContents 不用後面括號的部分。(不過我在實踐中發現改了之後地址也不會變,原因未明,谷歌也搜尋不到類似的情況)
{
markdownRemark(fields: { slug: { eq: $slug } }) {
id
excerpt
html
tableOfContents(pathToSlugField: "frontmatter.path")
frontmatter {
title
tags
date(formatString: "MMMM DD, YYYY")
}
}
}
接著你就能得到像這樣的目錄字串:
"<ul>
<li><a href="/2019-01-08-understand-mvvm/#%E5%89%8D%E8%A8%80">前言</a></li>
<li><a href="/2019-01-08-understand-mvvm/#mvvm-%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF">MVVM 基本資訊</a></li>
<li><a href="/2019-01-08-understand-mvvm/#mvvm-%E7%BB%93%E6%9E%84%E5%88%9D%E8%A7%81">MVVM 結構初見</a></li>
<li>
<p><a href="/2019-01-08-understand-mvvm/#mvvm-%E4%B8%8E-mvc-%E7%9A%84%E5%AF%B9%E6%AF%94">MVVM 與 MVC 的對比</a></p>
<ul>
<li><a href="/2019-01-08-understand-mvvm/#vue-%E7%9A%84-mvvm">Vue 的 MVVM</a></li>
<li><a href="/2019-01-08-understand-mvvm/#%E5%89%8D%E7%AB%AF-mvc">前端 MVC</a></li>
</ul>
</li>
<li><a href="/2019-01-08-understand-mvvm/#%E6%8B%93%E5%B1%95%EF%BC%9Areact-%E5%8F%AA%E6%98%AF-mvc-%E7%9A%84-v%EF%BC%9F">擴充:React 只是 MVC 的 V?</a></li>
<li><a href="/2019-01-08-understand-mvvm/#%E7%90%86%E8%A7%A3%E3%80%81%E4%BA%A4%E6%B5%81">理解、交流</a></li>
</ul>"
參考連結:https://www.gatsbyjs.org/pack...
注入錨點
你可能覺得上面的字串塞到網頁就大功告成……嗯我當時也這麼想。
現在你即使有這麼一個帶 url 的目錄,點選缺不會跳轉到對應位置。因為 markdown 轉換到 html 之後並沒有注入錨點。為解決這個問題要引入一個新外掛 gatsby-remark-autolink-headers。
npm install --save gatsby-remark-autolink-headers
安裝後進行如下配置
// In your gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [`gatsby-remark-autolink-headers`],
},
},
],
}
如果是看過之前的教程的話一定知道我的事例專案用了 prismjs,prismjs 外掛與 autolink 有迷之衝突,一定要把 autolink 放前,prismjs 放後:
// good
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-autolink-headers`,
`gatsby-remark-prismjs`,
],
},
}
// bad
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-prismjs`, // should be placed after `gatsby-remark-autolink-headers`
`gatsby-remark-autolink-headers`,
],
},
}
新增成功後由 md 檔案轉換得到的 html 字串裡的標題就會都帶上 id,這樣錨連結就能正常使用啦!
參考連結:https://www.gatsbyjs.org/pack...
調整樣式
以下是我的樣式程式碼,因為框架的全域性樣式對 ul 和 li 的影響挺大的,所以不少程式碼是用於修復的。另外是用媒體查詢在大屏時把目錄固定到左下角。
.css-toc {
color: $titleColor;
padding: 15px;
background: #fcfaf2;
margin-bottom: 25px;
> ul {
padding-left: 16px;
}
ul {
list-style-type: square;
list-style-position: outside;
margin-bottom: 0;
p {
vertical-align: top;
display: inline-block;
}
}
li {
margin-bottom: 0;
}
li > p {
margin-bottom: 0;
}
li > ul {
margin-top: 0;
}
}
@media screen and (min-width: 1045px) {
.css-toc {
position: fixed;
bottom: 0;
right: 0;
width: 200px;
max-height: 400px;
overflow: scroll;
font-size: 14px;
li > ul {
margin-left: 1rem;
}
}
}
完成效果圖