138 lines
3.1 KiB
Vue
138 lines
3.1 KiB
Vue
<script setup lang="ts">
|
||
import { computed } from 'vue'
|
||
|
||
interface ApiEntry {
|
||
name: string
|
||
description: string
|
||
type: string
|
||
defaultValue?: string
|
||
}
|
||
|
||
interface ApiDoc {
|
||
displayName: string
|
||
description: string
|
||
props: ApiEntry[]
|
||
events: ApiEntry[]
|
||
slots: ApiEntry[]
|
||
}
|
||
|
||
const props = defineProps<{
|
||
/** 组件名(与 packages/ui/src/<name>/ 目录一致),例如 "button" */
|
||
name: string
|
||
}>()
|
||
|
||
/**
|
||
* 数据由 scripts/gen-api.mjs 从组件源码生成,不要手写。
|
||
* 源码改动后执行 `pnpm gen:api` 即可刷新。
|
||
*/
|
||
const data = import.meta.glob('../../../data/api/*.json', { eager: true }) as Record<
|
||
string,
|
||
{ default: ApiDoc }
|
||
>
|
||
|
||
const doc = computed<ApiDoc | undefined>(() => {
|
||
const key = Object.keys(data).find((path) => path.endsWith(`/${props.name}.json`))
|
||
return key ? data[key].default : undefined
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<div v-if="doc" class="g3-api">
|
||
<p v-if="doc.description" class="g3-api__desc">{{ doc.description }}</p>
|
||
|
||
<template v-if="doc.props.length">
|
||
<h3>属性</h3>
|
||
<table>
|
||
<thead>
|
||
<tr><th>属性</th><th>说明</th><th>类型</th><th>默认值</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="item in doc.props" :key="item.name">
|
||
<td><code>{{ item.name }}</code></td>
|
||
<td>{{ item.description }}</td>
|
||
<td><code>{{ item.type }}</code></td>
|
||
<td><code>{{ item.defaultValue }}</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</template>
|
||
|
||
<template v-if="doc.events.length">
|
||
<h3>事件</h3>
|
||
<table>
|
||
<thead>
|
||
<tr><th>事件名</th><th>说明</th><th>类型</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="item in doc.events" :key="item.name">
|
||
<td><code>{{ item.name }}</code></td>
|
||
<td>{{ item.description }}</td>
|
||
<td><code>{{ item.type }}</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</template>
|
||
|
||
<template v-if="doc.slots.length">
|
||
<h3>插槽</h3>
|
||
<table>
|
||
<thead>
|
||
<tr><th>插槽名</th><th>说明</th></tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="item in doc.slots" :key="item.name">
|
||
<td><code>{{ item.name }}</code></td>
|
||
<td>{{ item.description }}</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</template>
|
||
</div>
|
||
|
||
<div v-else class="g3-api__missing">
|
||
未找到 <code>{{ name }}</code> 的 API 数据,请先执行 <code>pnpm gen:api</code>。
|
||
</div>
|
||
</template>
|
||
|
||
<style>
|
||
.g3-api__desc {
|
||
color: var(--ui-text-muted, #6b7280);
|
||
}
|
||
|
||
.g3-api h3 {
|
||
margin-top: 28px;
|
||
font-size: 16px;
|
||
}
|
||
|
||
.g3-api__missing {
|
||
padding: 12px 16px;
|
||
border: 1px dashed var(--ui-border, #e5e7eb);
|
||
border-radius: 8px;
|
||
font-size: 13px;
|
||
color: var(--ui-text-muted, #6b7280);
|
||
}
|
||
|
||
.g3-api table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.g3-api th,
|
||
.g3-api td {
|
||
padding: 10px 14px;
|
||
border: 1px solid var(--ui-border, #e5e7eb);
|
||
text-align: left;
|
||
vertical-align: top;
|
||
}
|
||
|
||
.g3-api th {
|
||
background: var(--ui-bg-muted, #f9fafb);
|
||
font-weight: 600;
|
||
}
|
||
|
||
.g3-api td code {
|
||
white-space: nowrap;
|
||
}
|
||
</style>
|