延續昨天的範例,我們在 pages/[...slug].vue 使用了元件 <ContentDoc />。今天就來談談 <ContentDoc /> 是什麼、它提供了哪些便利的參數,以及 Nuxt Content 還提供了哪些好用的元件。
<ContentDoc>可以設定條件及顯示 content 的元件。
設定包裹整個 content 的外層 tag,預設為 <div>。
設定 content 路徑,預設對應 $route.path 的 content/ 檔案。
設定是否隱藏摘要的內容。預設為 false(不隱藏)。
設定 content 的查詢條件,查詢條件包含的參數可以參考 <ContentQuery>,因為 <ContentDoc> 元件本身包含 <ContentRenderer> 及 <ContentQuery> 兩個元件。
設定是否將 content 的 Front-matter,帶入 html 的 head。預設為 true。
有提供 doc(content 資訊), isPartial(檔名前面是否有加 '_'), excerpt(在 <ContentDoc /> 設定的 excerpt)三個 slot props 可以使用。
原本的 <ContentDoc />:
// pages/[...slug].vue
<template>
<main>
<ContentDoc />
</main>
</template>
使用 default slot:
// pages/[...slug].vue
<template>
<main>
<ContentDoc v-slot="{ doc }">
<ContentRenderer :value="doc" />
</ContentDoc>
</main>
</template>
兩種方式渲染出來的頁面是相同的,差別在於使用 default slot,可以在渲染文件的區塊再添加其他內容,如下方範例把區塊內容變成文章並添加標題:
// pages/[...slug].vue
<template>
<main>
<ContentDoc v-slot="{ doc }">
<article>
<h1>{{ doc.title }}</h1>
<ContentRenderer :value="doc" />
</article>
</ContentDoc>
</main>
</template>
如果查不到對應路徑的 content,要顯示的內容。
// pages/[...slug].vue
<template>
<main>
<ContentDoc>
<template #not-found>
<div style="color: chocolate;">
OOps 你走錯路了 ¯\_(ツ)_/¯
</div>
</template>
</ContentDoc>
</main>
</template>
目前 content/ 目錄,且無另外設定 sources:
content
┣ guide
┃ ┣ index.md
┃ ┗ installation.md
┣ spy-family.md
因為沒有 content/spy-familyz.md,所以會顯示 #not-found 的內容。

官方文件描述 slot 是在渲染前預先顯示的內容,測試結果比較像是有對應的 content 文件,但文件沒有內容時顯示的內容。
The empty slot can be used to display a default content before rendering the document.
// pages/[...slug].vue
<template>
<main>
<ContentDoc>
<template #default="{ doc }">
<ContentRenderer :value="doc" />
</template>
<template #empty>
<h1 style="color: cadetblue;">
Document is empty
</h1>
</template>
</ContentDoc>
</main>
</template>
建立空白的檔案來測試:
// content/guide/index.md 此檔案無任何內容
實測結果:重新整理頁面沒有出現 #empty 內容,而是換到有文件無內容的路由時,才出現 #empty 內容。

<ContentNavigation>顯示 content 的導覽列。
目前 content/ 目錄:
content
┣ guide
┃ ┣ index.md
┃ ┗ installation.md
┣ spy-family.md
// pages/[...slug].vue
<template>
<main>
<nav>
<ContentNavigation v-slot="{ navigation }">
<ul>
<li v-for="link of navigation" :key="link._path">
<NuxtLink :to="link._path">
{{ link.title }}
</NuxtLink>
</li>
</ul>
</ContentNavigation>
</nav>
<ContentDoc />
</main>
</template>
此寫法僅會顯示第一層的資料,guide/index.md 及 spy-family.md,如果需要把全部資料都顯示的話,可以利用 childern 參數。

透過 /api/_content/navigation可以看到 navigation 的完整資料。

今天介紹了兩個 Nuxt Content 好用的元件,明天將帶大家實際使用這些元件來建立自己的部落格。