OpenDesign Components 组件开发指南:从文档规范到代码实现
OpenDesign Components 组件开发指南:从文档规范到代码实现
【免费下载链接】opendesign-componentsThe repository of OpenDesign components项目地址: https://gitcode.com/openeuler/opendesign-components
前往项目官网免费下载:https://ar.openeuler.org/ar/
OpenDesign Components 是 openEuler 社区推出的 Vue 3 组件库,为开发者提供了一套完整的企业级 UI 组件解决方案。本指南将带您深入了解组件开发的核心规范、文档体系和最佳实践,帮助您快速上手组件开发工作流程。
📋 组件开发工作流概览
OpenDesign 组件开发遵循严格的三层文档体系:注释标注(源码侧)、Demo case(交互侧)和文档页面(展示侧)。这三层通过自动化管线pnpm gen:api联动,确保文档与代码始终保持同步。
核心开发原则
- types.ts 是唯一真相来源- 所有 API 定义都通过 JSDoc 注释在 types.ts 中声明,禁止手动编辑自动生成的 API 文档文件
- 中英文文档同步维护- 每次修改必须同时更新 index.zh-CN.md 和 index.en-US.md 文件
- 自动化文档生成- 新增、修改或废弃任何 API 后必须运行
pnpm gen:api命令
🏗️ 组件文件结构规范
每个组件都遵循统一的目录结构,确保代码组织的一致性:
src/ComponentName/ ├── OComponent.vue # 模板 + <script setup> 实现 ├── index.ts # 组件安装和类型导出 ├── types.ts # Props 定义与 JSDoc 注释 └── style/ ├── var.scss # 组件局部 CSS 变量定义 ├── style.scss # 结构样式,引用 var.scss 变量 ├── media.scss # 响应式断点覆盖 ├── index.scss # 样式入口文件 └── index.ts # 样式依赖导入📝 注释规范与版本管理
JSDoc 注释要求
每个 prop 定义都必须包含完整的 JSDoc 注释,包括中英文描述:
/** * @zh-CN 按钮尺寸 * @en-US Button size * @defaultValue 'medium' * @since 1.0.0 */ size: { type: String as PropType<'small' | 'medium' | 'large'>, default: 'medium', },版本号管理策略
OpenDesign 采用两阶段版本号管理策略:
- 开发阶段:使用
@since NEXT占位符 - 发布阶段:批量替换为实际版本号
对于新增组件,在 sidebar 字段声明^NEXT;对于已有组件新增 API,逐项标注@since NEXT。
🎨 样式开发最佳实践
CSS 变量优先级规则
OpenDesign 遵循严格的 CSS 变量使用规范:
- 通用优先级:仓库内现有变量 > opendesign-token > 硬编码值
- margin/padding 例外:直接使用硬编码值,在 media.scss 中声明响应式
- 字号规则:font-size 和 line-height 必须成对存在
响应式设计规范
组件库支持多种响应式断点,您可以在media.scss中使用以下 mixin:
@include respond('<=laptop') { .o-component { --_box-height: 36px; } } @include respond('<=pad_v') { .o-component { --_box-height: var(--o-control_size-l); } }🔧 组件实现范式
范式 A:表单控件(Form Control)
所有具备用户输入语义的组件必须通过useFormField()composable 接入表单系统:
import { useFormField } from '../../_composables/use-form-field'; const { effectiveColor, inputId, isFocus, onFocus, onBlur, notifyChange } = useFormField(props, emit);这种方式自动处理表单验证状态、颜色覆盖和校验触发,适用于 OInput、OSelect、ODatePicker 等所有表单控件。
范式 B:组合组件(Group ↔ Item)
父子组件通过 provide/inject 模式通信,父组件管理状态,子组件读取和更新:
// 子组件中 const groupInjection = inject(groupInjectKey, null); // 状态计算优先读取 group 注入值 const isChecked = computed(() => { return groupInjection ? groupInjection.modelValue.value.includes(props.value) : localChecked.value; });范式 C:浮层触发器(Trigger + Panel)
根据用途选择合适的浮层基础组件:
- 功能性展开面板(下拉列表、日历等)→ 使用
OPopup+ClientOnly - 解释性气泡/提示(字段说明等)→ 使用
OPopover
📚 文档编写规范
文档目录结构
每个组件的__docs__/目录包含:
__docs__/ ├── index.zh-CN.md # 中文文档入口 ├── index.en-US.md # 英文文档入口 ├── OComponent-api.zh-CN.md # 自动生成的 API 文档(禁止手动编辑) ├── OComponent-api.en-US.md # 自动生成的 API 文档(禁止手动编辑) └── __case__/ ├── ComponentUsage.vue # 交互式 Usage Demo(必须) └── ComponentDemo.vue # 其他演示案例Demo Case 编写规范
每个 case 文件顶部使用<docs lang="md">自定义块编写说明文字:
<docs lang="md"> <!-- zh-CN --> ### 基础用法 这里写中文说明... <!-- en-US --> ### Basic Usage English description here... </docs>Usage Demo必须包含_oSchema和_oTemplate导出,支持交互式属性调整:
<script setup lang="ts"> import { propsToAttrStr } from '../../../_demo/utils'; import { DocDemoSchema, DocDemoTemplate } from '../../../_demo/types'; const _oSchema = { size: { type: 'list', list: ['large', 'medium', 'small'] }, disabled: { type: 'boolean' }, } satisfies Record<string, DocDemoSchema>; const _oTemplate: DocDemoTemplate<typeof _oSchema> = (props) => { return `<OButton ${propsToAttrStr(props)}>按钮</OButton>`; }; </script>🚀 SSR 兼容性要求
OpenDesign 全面支持服务端渲染,开发时需特别注意:
禁止在顶层访问浏览器 API
// ❌ 错误:在模块顶层访问 window const isMobile = window.innerWidth < 768; // ✅ 正确:在 onMounted 中访问 const isMobile = ref(false); onMounted(() => { isMobile.value = window.innerWidth < 768; });避免 Hydration Mismatch
- 不要在 setup/模板中使用
Math.random()、Date.now()等随机值 - 确保初始渲染与服务端一致,状态差异延迟到
onMounted后触发 - Teleport 和 OPopup 内容必须用
ClientOnly包裹
🛠️ 内部共享组件复用
OpenDesign 提供了丰富的内部共享组件,开发时应优先复用:
| 组件 | 用途 | 适用场景 |
|---|---|---|
InBox | 输入框视觉外壳 | 需要输入框外观的自定义组件 |
InInput | 带输入逻辑的文本框 | 单行文本输入场景 |
InTextarea | 多行文本输入 | 多行文本输入场景 |
ClientOnly | SSR 安全包装 | 包裹 Teleport/OPopup 内容 |
OPopup | 浮层基础容器 | 功能性展开面板 |
OPopover | 提示气泡 | 解释性提示内容 |
📊 代码质量检查
OpenDesign 对代码质量有严格要求,通过 ESLint 规则确保代码质量:
复杂度控制标准
- 圈复杂度:单个函数不超过 8
- 函数长度:单个函数不超过 300 行(composable 函数除外)
- 参数数量:函数参数不超过 3 个,超过时应封装为配置对象
质量检查流程
# 运行代码质量检查 pnpm exec eslint --config packages/skills/clean-code/eslint.diagnose.ts <文件路径>🔄 开发命令速查
常用开发命令
# 启动文档站开发服务器 pnpm docs:dev # 构建组件库 pnpm -C packages/opendesign build # 生成图标组件 pnpm -C packages/opendesign gen:icon # 生成 API 文档 pnpm gen:api # 代码质量检查 pnpm lint # 类型检查 pnpm type-check组件库构建流程
pnpm gen:icon- 从 SVG 重新生成图标组件pnpm build:component- 构建 ES/CJS 模块(preserveModules)pnpm build:style- 编译所有 SCSS 到对应路径
📈 版本发布流程
版本号替换
发布前需要批量替换@since NEXT为实际版本号:
- 更新所有 types.ts 中的
@since NEXT注释 - 更新文档中的
^NEXT标记 - 运行
pnpm gen:api重新生成 API 文档
废弃 API 处理
废弃 API 需要同时处理三个层面:
- 注释侧:添加
@deprecated标签和运行时警告 - 文档侧:添加 WARNING block 说明废弃原因和替代方案
- Demo 侧:为废弃功能创建单独的 case 文件
🎯 最佳实践总结
- 遵循三层文档体系:确保注释、Demo、文档页面同步更新
- 优先复用内部组件:避免重复造轮子,提高代码一致性
- 严格遵守 SSR 规范:确保组件在服务端渲染环境正常工作
- 使用设计 Token:统一使用
--o-*变量,保持设计一致性 - 自动化文档生成:每次 API 变更后运行
pnpm gen:api - 中英双语支持:所有文档和注释必须包含中英文版本
通过遵循这些规范和最佳实践,您将能够高效地为 OpenDesign Components 开发高质量、可维护的 Vue 3 组件。无论是修复现有组件的 bug,还是开发全新的功能模块,这套完整的开发指南都将为您提供清晰的路径和实用的工具。
记住:优秀的组件不仅是功能的实现,更是开发者体验的体现。OpenDesign 的设计哲学是通过严谨的规范和自动化工具,让组件开发变得简单而愉悦。🚀
【免费下载链接】opendesign-componentsThe repository of OpenDesign components项目地址: https://gitcode.com/openeuler/opendesign-components
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
