Markdown
用法
定义集合
import { defineCollection, defineContentConfig, z } from '@nuxt/content'
export default defineContentConfig({
collections: {
blog: defineCollection({
type: 'page',
source: 'blog/*.md',
schema: z.object({
date: z.string()
})
})
}
})
.md
文件 创建
在 content/blog/
目录中创建博客文章。
---
date: 2020-11-11
---
# Foo
这是 Foo 博客文章。
---
date: 2024-12-12
---
Hello
我是 bar。很高兴认识你。
查询 Markdown 文件
现在我们可以查询博客文章:
// 获取 foo 文章
const fooPost = await queryCollection('blog').path('/blog/foo').first()
// 查找所有文章
const allPosts = await queryCollection('blog').order('date', 'DESC').all()
显示 Markdown
要显示 Markdown 文件的内容,可以使用 <ContentRenderer>
组件。
<script setup>
const slug = useRoute().params.slug
const { data: post } = await useAsyncData(`blog-${slug}`, () => {
return queryCollection('blog').path(`/blog/${slug}`).first()
})
</script>
<template>
<!-- 以 Prose 和 Vue 组件渲染博客文章 -->
<ContentRenderer :value="post" />
</template>
<ContentRenderer>
组件和 Prose 组件
。Frontmatter
Frontmatter 是基于 Markdown 的 CMS 约定,用于为页面提供元数据,如描述或标题。在 Nuxt Content 中,frontmatter 使用 YAML 语法,采用 key: value
键值对形式。
这些数据在渲染内容时可用,可以存储你需要的任何信息。
语法
你可以在 content/
目录的 Markdown 文件顶部,用 ---
标识符声明 frontmatter 块。
---
title: '页面标题'
description: '页面的元描述'
---
<!-- 页面内容 -->
const home = await queryCollection('content').path('/').first()
console.log(home.title)
// => '页面标题'
console.log(home.description)
// => '页面的元描述'
console.log(home.body)
// => 页面内容的 AST 对象
原生参数
键 | 类型 | 默认值 | 描述 |
title | string | 页面第一个 <h1> | 页面标题,也会被注入到元信息 (metas) 中 |
description | string | 页面第一个 <p> | 页面描述,将显示在标题下方并注入到元信息 (metas) |
navigation | boolean | true | 定义页面是否包含在 queryCollectionNavigation 的返回值中。 |
MDC 语法
我们创建了 MDC 语法来增强 Markdown,赋予你在 Markdown 中集成带有插槽和属性的 Vue 组件的能力。
Vue 组件
你可以在 Markdown 文件中使用任意 Vue 组件。
我们有一种特殊语法,使在 Markdown 文件中使用组件更方便。
::component-name
默认插槽内容
::
块级组件
块级组件是接受 Markdown 内容或其他组件作为插槽的组件。
组件必须至少包含一个 <slot />
组件来接收格式化文本。
在 markdown 文件中,使用 ::
标识符调用组件。
::card
卡片的内容
::
<!-- components/content/Card.vue -->
<template>
<div class="p-2 border bg-white dark:bg-black dark:border-gray-700 rounded">
<slot />
</div>
</template>
卡片的内容
插槽
组件的插槽可以接受内容或其他组件。
- 默认插槽 在块级组件内渲染顶级内容或通过
#default
。 - 具名插槽 使用
#
标识符来渲染对应内容。
::hero
我的页面标题
#description
这部分将在 `description` 插槽内渲染。
::
<template>
<section>
<h1 class="text-4xl">
<slot mdc-unwrap="p" />
</h1>
<slot name="description" />
</section>
</template>
我的页面标题
这部分将在 description
插槽内渲染。
<slot />
组件。::the-title
一个由组件 **渲染** 的 [富文本](/)。
::
<template>
<h1 class="text-4xl">
<slot mdc-unwrap="p" />
</h1>
</template>
一个由组件 渲染 的 富文本。
Props 属性
使用 MDC 传递 props 给组件,有两种方式。
行内方式
{}
标识符使用简洁的 key=value
语法向组件传递属性。
::alert{type="warning"}
这是一个 **警告** 组件。
::
<script setup>
defineProps(['type'])
</script>
<template>
<div :class="[type]">
<slot mdc-unwrap="p" />
</div>
</template>
多个属性用空格分隔:
::alert{type="warning" icon="exclamation-circle"}
出错了!
::
v-bind
简写 :
也可用来绑定 frontmatter 中的属性值:
---
type: "warning"
---
::alert{:type="type"}
你的警告
::
如果要传递数组或对象作为属性给组件,可以将它们作为 JSON 字符串,属性键名前加冒号以自动解码 JSON 字符串。注意,这种情况下应使用单引号包裹字符串值,以便使用双引号传递有效的 JSON 字符串:
::dropdown{:items='["Nuxt", "Vue", "React"]'}
::
::dropdown{:items='[1,2,3.5]'}
::
::chart{:options='{"responsive": true, "scales": {"y": {"beginAtZero": true}}}'}
::
YAML 方式
YAML 方式用 ---
标识符声明逐行一个 prop,便于可读性。
::icon-card
---
icon: IconNuxt
description: 发挥 Nuxt 及其生态系统的全部力量。
title: Nuxt 架构。
---
::
<script setup>
defineProps({
title: {
type: String,
default: '默认标题'
},
description: {
type: String,
default: '默认描述'
},
icon: {
type: String,
default: 'IconMarkdown'
}
})
</script>
<template>
<div class="p-6 border bg-white dark:bg-black dark:border-gray-700 rounded">
<component :is="icon" class="w-20 h-20" />
<h2 class="text-3xl font-semibold mb-2">
{{ title }}
</h2>
<p>{{ description }}</p>
</div>
</template>
Nuxt 架构。
发挥 Nuxt 及其生态系统的全部力量。
属性 (Attributes)
属性对于高亮和修改段落部分内容很有用。语法与行内组件和 Markdown 链接语法非常相似。
可能的值包括所有命名属性、以 .class-name
形式的类名,以及以 #id-name
形式的 ID。
Hello [World]{style="color: green;" .custom-class #custom-id}!
Hello World !
除了 mdc 组件和 span
,属性语法还适用于图像、链接、内联 code
、*粗体* 和 _斜体_ 文本。
属性适用于:
- [链接](#attributes){style="background-color: pink;"}, `代码`{style="color: cyan;"},
- _斜体_{style="background-color: yellow; color:black;"} 和 **加粗**{style="background-color: lightgreen;"} 文本。
属性适用于:
- 链接,
代码
, - 斜体 和 加粗 文本。
绑定数据
你可以使用 {{ $doc.variable || 'defaultValue' }}
语法在 Markdown 文档中绑定数据。这些值可以在文档顶部的 YAML frontmatter 中定义,在每个 MDC 组件内定义,或通过 <ContentRenderer>
组件的 data
属性注入。
在 YAML 中定义
---
title: '页面标题'
description: '页面元描述'
customVariable: '自定义值'
---
# 标题是 {{ $doc.title }} ,customVariable 是 {{ $doc.customVariable || 'defaultValue' }}
在外部定义 <ContentRenderer>
<template>
<div>
<ContentRenderer :value="data" :data="mdcVars"/>
<button type="button" v-on:click="mdcVars.name = 'Hugo'">更改名称</button>
</div>
</template>
<script setup lang="ts">
const { data } = await useAsyncData(() => queryCollection('content').path('/test').first());
const mdcVars = ref({ name: 'Maxime'});
</script>
# 你好 {{ $doc.name || '世界' }}
Prose 组件
在 Nuxt Content 中,prose 表示由 Markdown 语法生成的 HTML 标签,如标题和链接。
每个 HTML 标签对应一个 Vue 组件,你可以根据需求覆盖它们,例如 <p>
对应 <ProseP>
。
如果想定制 Prose 组件,建议的步骤如下:
- 查看原始的 组件源码。
- 使用完全相同的 props。
- 在你的
components/content/
目录下,命名相同文件。 - 根据需要定制 🚀。
代码高亮
Nuxt Content 使用 Shiki 实现代码高亮,主题与 VSCode 一致。
代码高亮同时适用于 ProsePre
和 ProseCode
。
代码块的每一行数字存储在 line
属性中,便于单行标注与样式定制。
图片
你可以将图片添加到你的 public
目录:
content/
index.md
public/
image.png
nuxt.config.ts
package.json
然后在 content
目录的 markdown 文件中这样使用:

摘要
内容摘要或概要可以通过使用 <!--more-->
作为分隔符从内容中提取。
---
title: 介绍
---
学习如何使用 `@nuxt/content`。
<!--more-->
更多分割线后的完整内容。
描述字段 (description) 会包含摘要内容,除非 frontmatter 中已定义。
如果文本中没有 <!--more-->
分隔符,则摘要字段为未定义。
excerpt
字段。const content = defineCollection({
type: 'page',
source: '**',
schema: z.object({
excerpt: z.object({
type: z.string(),
children: z.any(),
}),
}),
})
示例变量会注入到文档中:
{
"excerpt": Object,
"body": Object,
// ... 其他键
}