基于 docs.comphub.cn 官方规范,快速生成符合 comp-hub 发布标准的业务组件。
ComponentName/ # 组件名称 = 文件夹名(全局唯一)
├── index.vue # 入口文件(必需)
├── README.md # 组件文档(建议)
├── comp.json # 配置文件(自动生成,name + version + __id__)
├── main.js # UI 框架注册(可选,需要第三方 UI 库时添加)
├── demo/ # 预览示例
│ ├── index.vue # 小窗预览(列表页展示)
│ └── full.vue # 全屏预览(详情页展示,建议配置)
└── assets/ # 静态资源(如有)
公司名-业务域-组件名,如 alipay-data-table- 和下划线 _✅ import bgIcon from './assets/bg.png'
❌ import bgIcon from '@/assets/bg.png'
index.vue 作为组件入口组件预览基于 Vue 运行,所有 Vue 生态下的 UI 框架均可直接使用。只需在组件根目录添加 main.js 文件,引入并注册即可。
import Vue from 'vue';
import Antd from 'ant-design-vue';
import 'ant-design-vue/dist/antd.css';
Vue.use(Antd);
Vue 2 默认导出 Vue 构造函数,直接调用 Vue.use() 注册插件即可。
Vue 3 不再默认导出,所有导出都是具名导出。在 comp-hub 渲染环境下,组件预览的 app 实例由工具内部创建,main.js 无法通过 createApp() 创建 app。为此,comp-hub 会将内部 app 实例挂载到 Vue 命名空间上,直接通过 Vue.app 使用即可:
import * as Vue from 'vue';
import ArcoVue from '@arco-design/web-vue';
import '@arco-design/web-vue/dist/arco.css';
Vue.app.use(ArcoVue);
这与官方 app.use() 的调用方式不同,但功能等价——注册后,组件预览即可使用该 UI 框架的所有组件,无需在每个组件中重复导入。
demo/mini.vue — 小窗预览,需固定内容尺寸(如 320×240)并使用缩放居中 API(见第 8 节)demo/full.vue — 全屏预览,展示完整功能,宽高继承父元素(width: 100%; height: 100%),无需缩放))scoped 隔离样式comp-hub 预览环境会为组件 Vue 实例注入两个方法,帮助 mini 面板的固定尺寸内容自适应预览面板大小。
> 重要:此 API 仅用于 demo/mini.vue(小窗预览)。demo/full.vue(全屏预览)不需要缩放,直接设置 width: 100%; height: 100% 继承父元素即可。
这些方法仅在 comp-hub 预览环境中存在,调用前务必做判空保护。
$getScaleStyle(params) — 主动查询缩放样式同步获取基于内容尺寸与缩放模式计算出的缩放 + 居中样式。
type ScaleMode = "widthFirst" | "heightFirst" | "contain" | "cover"
interface ScaleStyle {
transform: string // 例如 "translate(100px, 50px) scale(0.75)"
transformOrigin: string // 固定为 "left top"
}
this.$getScaleStyle({
mode: ScaleMode // 缩放模式
width: number // 组件内容宽度(px)
height: number // 组件内容高度(px)
}): ScaleStyle
缩放模式说明:
| 模式 | 行为 |
|---|---|
| --- | --- |
"widthFirst" | 按容器宽度缩放,高度可能溢出 |
"heightFirst" | 按容器高度缩放,宽度可能溢出 |
"contain" | 等比例缩放,内容始终完整可见(默认推荐) |
"cover" | 等比例缩放,填满容器(可能裁切超出部分) |
所有模式均通过 translate 将内容居中于容器内。
Vue 2 Options API 示例(mini 面板):
<template>
<div :style="$getScaleStyle({ mode: 'contain', width: 320, height: 240 })">
<!-- 组件内容 -->
</div>
</template>
Vue 3 Composition API 示例(mini 面板):
import { getCurrentInstance } from "vue"
const instance = getCurrentInstance()
const scaleStyle = (instance?.proxy as any)?.$getScaleStyle?.({
mode: "contain",
width: 320,
height: 240
})
$onScaleChange(params, callback) — 订阅容器尺寸变化注册时立即回调一次当前 scale,之后容器大小变化时自动回调最新值。返回取消订阅函数。
const unsubscribe = this.$onScaleChange(
params: { mode: ScaleMode, width: number, height: number },
callback: (style: ScaleStyle) => void
): () => void
Vue 2 Options API 示例(mini 面板):
<script>
export default {
data() {
return { scaleStyle: {} }
},
mounted() {
this._unsub = this.$onScaleChange(
{ mode: "contain", width: 320, height: 240 },
(style) => { this.scaleStyle = style }
)
},
beforeDestroy() {
this._unsub?.() // 取消订阅,防止内存泄漏
}
}
</script>
Vue 3 Composition API 示例(mini 面板):
<script setup>
import { ref, getCurrentInstance, onBeforeUnmount } from "vue"
const instance = getCurrentInstance()
const scaleStyle = ref({})
const unsub = (instance?.proxy as any)?.$onScaleChange?.(
{ mode: "contain", width: 320, height: 240 },
(style) => { scaleStyle.value = style }
)
onBeforeUnmount(() => unsub?.())
</script>
<template>
<div class="mini-wrapper" :style="scaleStyle">
<div class="mini-content">
<!-- 按 320×240 设计的内容 -->
...
</div>
</div>
</template>
<script setup>
import { ref, getCurrentInstance, onBeforeUnmount } from "vue"
const instance = getCurrentInstance()
const scaleStyle = ref({})
const unsub = (instance?.proxy as any)?.$onScaleChange?.(
{ mode: "contain", width: 320, height: 240 },
(style) => { scaleStyle.value = style }
)
onBeforeUnmount(() => unsub?.())
</script>
<style scoped>
.mini-wrapper {
transform-origin: left top;
}
.mini-content {
width: 320px;
height: 240px;
overflow: hidden;
}
</style>
<template>
<div class="full-content">
<!-- 完整功能展示,宽高继承父元素 -->
<MyComponent />
</div>
</template>
<style scoped>
.full-content {
width: 100%;
height: 100%;
overflow: hidden;
}
</style>
> 关键区别:mini 面板固定内容尺寸 + 缩放 API;full 面板直接 100% 继承,不调用任何缩放 API。
$onScaleChange 响应容器变化,避免反复调用 $getScaleStylebeforeDestroy / onBeforeUnmount 中调用 unsubscribe(),防止内存泄漏contain 是默认安全选择 — 确保内容在小型预览面板中也完整可见// Vue 2 安全调用
if (this.$onScaleChange) {
this._unsub = this.$onScaleChange(
{ mode: "contain", width: 320, height: 240 },
(style) => { this.scaleStyle = style }
)
}
index.vue(入口组件)demo/mini.vue(小窗预览,固定尺寸 + 缩放居中 API)demo/full.vue 或 demo/full/index.vue(全屏预览,宽高 100% 继承父元素,不缩放。复杂组件可拆为多文件目录结构)README.md(包含属性表、事件、使用示例、依赖说明、更新日志)—— 必须遵守标题命名规范(见下方)README.md 中的所有标题(以 # 开头的行)必须通过平台验证,否则组件上传失败。生成时严格遵守以下规则:
### 1. xx、## 2.xx,应改为 ### xx、## xx# — 井号(会被解析为 Markdown 标题标记) `` — 反引号(Markdown 代码标记)+、:、&、<、>、"、'、/、\、|、*、[、]、{、}、(、)、!、?、@、$、%、^、=、~、.、,、;\n、\r)、制表符(\t)、换页符、垂直制表符-_()正确示例:
## 基础搜索和分页
## 手动搜索(关闭自动查询)
## 分页自定义
## i18n 支持
## 分页参数名映射
错误示例:
## 1. 基础搜索 ← 禁止以数字开头
## 基础搜索 + 分页 ← 禁止 + 字符
## 手动搜索(autoQuery: false) ← 禁止英文括号 () 和冒号 :
## 读取 `col.value` ← 禁止反引号
## 什么是 BaseTable? ← 禁止 ?
> 标题中如需表达英文技术术语,可用中文替代或直接拼写为字母(如 i18n),不要使用特殊符号。
comp.json({ "name": "...", "version": "1.0.0" },__id__ 由平台自动生成)main.js主版本.次版本.补丁版本共 2 个版本