163 lines
3.5 KiB
Vue
163 lines
3.5 KiB
Vue
<template>
|
||
<div v-if="api" class="tui-api">
|
||
<section v-if="api.props.length > 0">
|
||
<h3>Props</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>名称</th>
|
||
<th>类型</th>
|
||
<th>默认值</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="row in api.props" :key="row.name">
|
||
<td class="name">
|
||
<code v-text="row.name" />
|
||
<span v-if="row.required" class="required" title="必填">*</span>
|
||
</td>
|
||
<td><code v-text="row.type" /></td>
|
||
<td><code v-text="row.defaultValue" /></td>
|
||
<td v-text="row.description" />
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section v-if="api.events.length > 0">
|
||
<h3>Events</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>名称</th>
|
||
<th>参数</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="row in api.events" :key="row.name">
|
||
<td><code v-text="row.name" /></td>
|
||
<td><code v-text="row.type" /></td>
|
||
<td v-text="row.description" />
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section v-if="api.slots.length > 0">
|
||
<h3>Slots</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>名称</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="row in api.slots" :key="row.name">
|
||
<td><code v-text="row.name" /></td>
|
||
<td v-text="row.description" />
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<section v-if="api.exposes.length > 0">
|
||
<h3>Expose</h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>名称</th>
|
||
<th>类型</th>
|
||
<th>说明</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="row in api.exposes" :key="row.name">
|
||
<td><code v-text="row.name" /></td>
|
||
<td><code v-text="row.type" /></td>
|
||
<td v-text="row.description" />
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</section>
|
||
|
||
<p v-if="isEmpty && !api.parsed" class="notice warn">
|
||
未能从源码中解析出 API 信息,请检查组件是否使用了 defineProps / defineEmits / defineExpose。
|
||
</p>
|
||
<p v-else-if="isEmpty" class="notice">
|
||
该组件不需要任何 props、events、slots 或实例方法。
|
||
</p>
|
||
</div>
|
||
|
||
<p v-else class="notice warn" v-text="`未找到组件 ${name} 的 API 数据,请检查 components.ts 中的 name 与 entry 是否正确`" />
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { computed } from "vue";
|
||
import apiMap from "virtual:timi-api";
|
||
|
||
/**
|
||
* 组件 API 表格。
|
||
*
|
||
* 数据来自构建期 `vue-docgen-api` 对组件源码的解析结果,
|
||
* 无需在 markdown 中手写 props / events / slots 表格。
|
||
* 某个分区没有内容时整段不渲染,避免出现空表。
|
||
*/
|
||
const props = defineProps<{
|
||
/** 组件名,需与 components.ts 中的 name 一致。 */
|
||
name: string;
|
||
}>();
|
||
|
||
const api = computed(() => apiMap[props.name]);
|
||
|
||
const isEmpty = computed(() => {
|
||
if (!api.value) {
|
||
return false;
|
||
}
|
||
const { props: propRows, events, slots, exposes } = api.value;
|
||
return propRows.length === 0 && events.length === 0 && slots.length === 0 && exposes.length === 0;
|
||
});
|
||
</script>
|
||
|
||
<style lang="less" scoped>
|
||
.tui-api {
|
||
section {
|
||
margin-bottom: 1.5rem;
|
||
|
||
&:last-child {
|
||
margin-bottom: 0;
|
||
}
|
||
}
|
||
|
||
h3 {
|
||
margin: 1.5rem 0 .75rem;
|
||
font-size: 1rem;
|
||
}
|
||
|
||
.name {
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.required {
|
||
margin-left: .125rem;
|
||
color: var(--vp-c-danger-1);
|
||
}
|
||
|
||
.notice {
|
||
margin: 1rem 0;
|
||
padding: .75rem 1rem;
|
||
font-size: .875rem;
|
||
border-radius: .5rem;
|
||
color: var(--vp-c-text-2);
|
||
background: var(--vp-c-bg-soft);
|
||
|
||
&.warn {
|
||
color: var(--vp-c-warning-1);
|
||
background: var(--vp-c-warning-soft);
|
||
}
|
||
}
|
||
}
|
||
</style>
|