source-filesystem
: 將文件轉換為可以使用GraphQL在組件中獲取的內容transformer-remark
: 把md文件轉換成html。github-markdown-css
: 把md檔案的內容加上css。將文件轉換為可以使用GraphQL在組件中獲取的內容。
yarn add @gridsome/source-filesystem
npm install @gridsome/source-filesystem
Markdown transformer for Gridsome with Remark. 把md文件轉換成html。
yarn add @gridsome/transformer-remark
npm install @gridsome/transformer-remark
一般來說這兩個套件會一起用,用法如下:
// gridsome.config.js
module.exports = {
plugins: [
{
use: '@gridsome/source-filesystem',
options: {
path: 'frontend/**/*.md',
typeName: 'mdPost',
remark: {
// remark options
}
}
}
],
transformers: {
remark: {
// global remark options
}
}
}
path
:md檔的位置。
typeName
: 表示會在graphQL裡面建立一個以mdPost
為主的架構樹。
在整個資料夾底下第一層建立frontend
資料夾放置.md
的檔案。
在.md檔案裡面的開頭用- - -
包含的屬性,會變成graphQL中的node其中的屬性,可以在node中取得tags
,date
,description
,cover_image
。
// .md
---
tags: ['frontend work','css','flexbox']
date: 2020-02-05
description: 在css中,可以使用flex來做一維布局的排版...
cover_image: ../img/flexbox.png
---
這時候在終端機按下ctrl+c
終止,輸入gridsome develop
,點下grapgQL data的網址http://localhost:8082/___explore
。
到達這個地方,按下旁邊docs展開,會看到網站的資料被載入graphQL data,包含了剛剛設定的mdPost
還有所有mdPost
的集合allMdPost
。
在左邊我們練習載入所有的mdPost
graphQL語法,利用一個query包住,就可以把結果列出來在右邊的部分,表示我們下的搜尋語法,會得到右邊的結果。
query{
allMdPost{
edges{
node{
path
tags
date
description
title
content
cover_image
}
}
}
}
將這一段query複製到Frontend.vue
裡面,並加上page-query
的標籤,表示這一page下的query內容
可以在下面script使用this.$ page.allMdPost.edges
或是在html的部分使用{{$page.allMdPost.edges}}
列出來。
// 列出所有文章標題
ul
li(v-for="{node} in $page.allMdPost.edges")
p {{node.title}}
這樣就成功載入了!
然後做一下排版和css調整,就可以得到下方的樣子。
//
ul
li(v-for="{node} in $page.allMdPost.edges")
.post
.img_box
g-image(:src="node.cover_image" fit="contain")
time {{getDate(node.date)}}
.dark_cover
.tags
span(v-for="tag in tags") {{tag}}
h2(v-html="node.title")
hr
div.short-text(v-html="node.excerpt || node.description")
g-link.more-link(:to="node.path") MORE
這段有一些幾個需要解釋的地方,
g-image
: gridsome有一個內置的g-image
組建,可以輸出優化的漸進圖像,還可以調整大小來裁切。
預設情況是base64
的模糊圖像,使得模糊圖像位於與真實圖像尺寸相同的容器中,因此在加載圖像時不會跳躍。
當圖像在視口中時,一個Intersection Observer會將基本圖像交換為較大的圖像。(延遲加載)
可以設定屬性來裁剪,更多屬性可以參考文件。<g-image src="./image.png" width="500" height="500" fit="contain"/>
getDate
: 是底下的methods方法,寫在這裡。// Frontend.vue
export default {
methods:{
getDate(dateStr){
let date = new Date(dateStr);
return `${date.getMonth() + 1}/${date.getDate()},${date.getFullYear()}`;
}
}
};
g-link(:to="node.path")
:最後的這個連結前往這篇文章的path,點下之後卻出現not found。
還記得嗎?我們在gridsome.config.js
有設定如下:// gridsome.config.js
{
use: '@gridsome/source-filesystem',
options: {
path: 'frontend/**/*.md',
typeName: 'mdPost',
remark: {
// remark options
}
}
}
表示我們需要在templates
裡面建立一個mdPost.vue
來裝該篇.md文章,找不到mdPost.vue
作為該路竟要前往的地方,所以才出現not found。
Templates
在collections 被用來為nodes創造單一page,nodes需要一個相對應的page來展現在他相對應的url上。所以我們單篇的文章套用的page就會變成這個檔案: mdPost.vue
。
graphQL必須動態載入單篇文章,我們用$ path
作為參數傳入,設定方法為在query後面定義的參數類型$ path:String!
,驚嘆號表示required
,在篩選的屬性再用$path
傳入。
id
和path
,用其他屬性例如title會報錯。主要的內容如下:
<template lang="pug">
div
p this is md custom post
p {{$page}}
.time
time 更新日期: {{formatDate($page.mdPost.date)}}
.markdown-body(v-html="$page.mdPost.content")
</template>
<page-query>
query ($path:String!){
mdPost(path:$path){
id
path
content
date
title
}
}
</page-query>
文章內容利用$page.mdPost.content
來取得。此時我們的版面還沒加上css,使用一個套件github-markdown-css
讓版面有美化過。
md
的div加上markdown-body
的class。// Blog.vue 引用
@import url("https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css");
.markdown-body {
box-sizing: border-box;
min-width: 200px;
max-width: 980px;
margin: 0 auto;
padding: 45px;
}
@media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
// Post.vue
div.markdown-body(v-html="$page.post.content")
src/main.js
中引用// src/main.js
export default function (Vue, { router, head, isClient }) {
// 從這裡加入外部css files
head.link.push({
rel: 'stylesheet',
href: 'https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/3.0.1/github-markdown.min.css'
})
}
這樣就完成Frontend.vue
以及mdPost.vue
的主要畫面了。
屏東人,前端工程師,愛泰人。