在有了文章屬性後,就可以嘗試為文章建立專屬顯示頁面了。
首先建立名為 @/pages/articles/[...slug].vue
的檔案,並填寫
<template>
<ContentDoc v-slot="{ doc }">
<TheArticle :post="doc" />
</ContentDoc>
</template>
[...slug].vue
同之前講的,會將訪問 localhost/articles/xxxx
的所有路徑都以這個 Vue Component 去渲染,除非我另外在 @/pages/articles/
下方建立其他頁面。
這裡的 <ContentDoc>
如同之前所說是讀取對等路徑的 Markdown 檔案,並透過 v-slot="{ variable }"
取得該檔案物件與其屬性,包括我們昨天在 frontmatter 定義的那些。
並且將該檔案物件(上面範例的 doc
)作為 props 傳給 <TheArticle />
。這時候會報錯說找不到 <TheArticle/>
,所以接下來就來建立 @/components/TheArticle.vue
:
<template>
<article class="pb-4">
<header class="pb-6" >
<h1 class="tracking-tight font-extrabold text-gray-900 text-2xl leading-6 mb-1">
{{ post.title }}
</h1>
<!-- 預計放上發表時間 -->
</header>
<div class="my-4 break-word flex flex-col">
<div class="mr-4">
<ContentRenderer :value="post" class="prose" />
</div>
</div>
<footer class="pt-10">
<!-- 預計放上文章標籤 -->
</footer>
</article>
</template>
<script setup lang="ts">
import { ParsedContent } from "@nuxt/content/dist/runtime/types"
interface Post extends ParsedContent {
title: string
created_at: string
published_at: string
tags: string[]
}
defineProps<{
post: Post
}>()
</script>
因為是使用 TypeScript,所以在 <script />
去定義了 Post 介面給 props 的變數使用,這個介面拓展自原本 doc 變數的型別 ParsedContent
,這樣除了自定義的屬性外,也能讀取既有的屬性。
接著就是先透過 TailwindCSS 簡單架構出文章的渲染畫面,包括標題與內文。發表時間與標籤就等明天再來處理。
這時候我們更新 @/content/articles/demo.md
作為示範:
---
title: 興別們紅己海所在照落
created_at: 2023-09-26T23:03:49.867+08:00
published_at: 2023-09-26T23:08:01.763+08:00
tags:
- template
- obsidian
- nuxt
---
出合美於也來藥他人友直最的子是,果那臺量是動一大活這容始人在就:及管想經界業種列拉供!我歡士樓指作師切可旅驚中便到生……能人二為自物望來... <下略>
成果如圖: