ComponentExample

GitHub查看源码
ComponentExample 在文档中嵌入交互式 Vue 组件示例,实时渲染预览效果并展示带语法高亮的源代码,支持折叠显示。通过 useFetchComponentExample 获取构建时注册的示例文件,显著提升文档的可读性和用户体验。

用法

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
---
::

仅客户端渲染

如果示例内部会直接使用 windowdocumentsetInterval 这类浏览器 API,可以加上 client-only="true",让预览组件仅在客户端渲染,避免 SSR 阶段触发警告:

md
:component-example{name="AccordionExample" client-only="true"}

API

Props

Prop Default Type
namestring
iframefalseboolean | { [key: string]: any; }

是否在 iframe 中渲染组件

props{ [key: string]: any; }
collapsefalseboolean | { 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; }[]

链接到组件的可变属性列表

highlightsnumber[]

代码块中需要高亮的行号列表

lang'vue'string
filenamestring

覆盖用于代码块的文件名

iframeMobilefalseboolean

是否在移动端尺寸的 iframe 视口中显示组件

prettierfalseboolean

是否使用 Prettier 格式化代码

previewtrueboolean

是否显示预览 当设置为 false 时,将显示文件名

sourcetrueboolean

是否显示源代码

overflowHiddenboolean

是否在包装器上添加 overflow-hidden

clientOnlyfalseboolean

是否只在客户端渲染预览组件,适用于依赖 window / setInterval 等浏览器 API 的示例

elevatedboolean

是否添加 background-elevated 到 wrapper

Slots

Slot Type
options{}
code{}

ComponentExampleExtras

在消费方仓库新建 app/components/content/ComponentExampleExtras.vue 即可在示例容器内叠加 ThemeVisualizer、Playground 按钮等附加 UI,无需 fork ComponentExample。Layer 默认提供空实现。

可用 props:

Prop类型说明
namestringMDC name="..." 的原始值,即示例文件名
camelNamestring示例名的 camelCase 形式
pascalNamestring示例名的 PascalCase 形式,来自 useFetchComponentExample
effectivePropsRecord<string, any>当前生效的合并 props(含 options)
optionsArray<{ name, label, ... }> | undefinedoptions 配置原样透传
wrapperContainerHTMLElement | null最外层 wrapper,用于 popover / 高亮框定位
componentContainerHTMLElement | 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
Copyright © 2024 - 2026