用法
ComponentExample 用于在文档中嵌入可交互的组件示例。它会自动加载组件,并展示实时预览和源代码。
基本用法
在您的 Markdown 文档中使用 :component-example 指令:
<script setup lang="ts">
import type { AccordionItem } from '@nuxt/ui'
const items = [
{
label: 'Icons',
icon: 'i-lucide-smile',
content: 'You have nothing to do, @nuxt/icon will handle it automatically.'
},
{
label: 'Colors',
icon: 'i-lucide-swatch-book',
slot: 'colors' as const,
content: 'Choose a primary and a neutral color from your Tailwind CSS theme.'
},
{
label: 'Components',
icon: 'i-lucide-box',
content: 'You can customize components by using the `class` / `ui` props or in your app.config.ts.'
}
] satisfies AccordionItem[]
</script>
<template>
<UAccordion :items="items">
<template #colors="{ item }">
<p class="text-sm pb-3.5 text-primary">
{{ item.content }}
</p>
</template>
</UAccordion>
</template>
:component-example{name="AccordionExample"}
高级配置
md
::component-example
---
name: AccordionExample
highlights: [10, 15, 20]
collapse: true
---
::
仅客户端渲染
如果示例内部会直接使用 window、document、setInterval 这类浏览器 API,可以加上 client-only="true",让预览组件仅在客户端渲染,避免 SSR 阶段触发警告:
md
:component-example{name="AccordionExample" client-only="true"}
API
Props
| Prop | Default | Type |
|---|---|---|
name | string | |
iframe | false | boolean | { [key: string]: any; }是否在 iframe 中渲染组件 |
props | { [key: string]: any; } | |
collapse | false | boolean | { icon?: string; name?: string; openText?: string; closeText?: string; open?: boolean; }是否折叠代码块 |
options | { type?: string; alias?: string; name: string; label: string; items?: any[]; default: any; multiple?: boolean; }[]链接到组件的可变属性列表 | |
highlights | number[]代码块中需要高亮的行号列表 | |
lang | 'vue' | string |
filename | string覆盖用于代码块的文件名 | |
iframeMobile | false | boolean是否在移动端尺寸的 iframe 视口中显示组件 |
prettier | false | boolean是否使用 Prettier 格式化代码 |
preview | true | boolean是否显示预览
当设置为 |
source | true | boolean是否显示源代码 |
overflowHidden | boolean是否在包装器上添加 overflow-hidden | |
clientOnly | false | boolean是否只在客户端渲染预览组件,适用于依赖 window / setInterval 等浏览器 API 的示例 |
elevated | boolean是否添加 background-elevated 到 wrapper |
Slots
| Slot | Type |
|---|---|
options | {} |
code | {} |
ComponentExampleExtras
在消费方仓库新建 app/components/content/ComponentExampleExtras.vue 即可在示例容器内叠加 ThemeVisualizer、Playground 按钮等附加 UI,无需 fork ComponentExample。Layer 默认提供空实现。
可用 props:
| Prop | 类型 | 说明 |
|---|---|---|
name | string | MDC name="..." 的原始值,即示例文件名 |
camelName | string | 示例名的 camelCase 形式 |
pascalName | string | 示例名的 PascalCase 形式,来自 useFetchComponentExample |
effectiveProps | Record<string, any> | 当前生效的合并 props(含 options) |
options | Array<{ name, label, ... }> | undefined | options 配置原样透传 |
wrapperContainer | HTMLElement | null | 最外层 wrapper,用于 popover / 高亮框定位 |
componentContainer | HTMLElement | null | 示例组件实际渲染容器,用于 querySelector('[data-slot]') 等 DOM 扫描 |
示例:叠加 ThemeVisualizer
参考 Nuxt UI 的 ComponentThemeVisualizer.vue 实现一个 LazyComponentThemeVisualizer,然后在覆盖文件中接入。
docs/app/components/content/ComponentExampleExtras.vue
<script setup lang="ts">
import { camelCase } from 'scule'
defineProps<{
wrapperContainer: HTMLElement | null
componentContainer: HTMLElement | null
}>()
const route = useRoute()
const slug = computed(() => camelCase(route.path.split('/').pop() ?? ''))
</script>
<template>
<LazyComponentThemeVisualizer
:slug="slug"
:container="componentContainer"
:position-container="wrapperContainer"
/>
</template>
Changelog
No recent changes