packages/o2-design/skills/o2-design-overview/SKILL.md
o2-design 组件库开发必读
npx skillsauth add moushudyx/working-skills o2-design-overviewInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
o2-design 组件库是极其特殊的组件库,内部使用 Vue2 的响应式方法,形成特殊的响应式编程体验
严禁猜测组件功能、参数、使用方法等,必须先完整阅读文档,此组件库任何误用都可能导致页面崩溃
仅能在文档缺失或者模糊时,根据现有代码做有限推测,并明确提示用户这些推测内容需人工甄别
不要与 Vue 中的同名概念混淆,o2-design 中的 setup 是一个特殊的函数
onMounted 等生命周期函数、useTableOption 等特殊功能函数仅能在 setup 中调用
// designComponent 是 o2-design 定义组件的核心函数
const MyComponent = designComponent({
// inheritAttrs: false, // 类似 Vue 的参数透传, 默认为 true
props: {}, // 组件 props 定义
slots: ['default'],
emits: { onClick: (e: React.MouseEvent) => true },
// 没有定义在 props 中的参数会被放在 attrs 中, 包括组件标签上未声明的属性和事件
setup({ props, slots, event: { emit }, attrs }) {
// 这里是 setup 函数,这里可以调用 onMounted、useTableOption 等特殊功能函数
return () => <div onClick={(e) => emit.onClick(e)}>{slots.default()}</div>; // render 函数,返回组件的 JSX 结构
},
});
// designPage 是 designComponent 的简化, 只接受一个 setup 函数
const MyComponent2 = designPage((props) => {
// 这里是 setup 函数,这里可以调用 onMounted、useTableOption 等特殊功能函数
return () => <div onClick={props.onClick}>{props.children}</div>; // render 函数,返回组件的 JSX 结构
});
o2-design 内部使用了 Vue2 的响应式相关代码,组件开发者可以直接使用 reactive、computed、watch 等函数创建响应式数据,组件会自动追踪这些数据的变化并触发更新
import { reactive, computed, watch, onMounted, designPage } from 'o2-design';
const globalState = reactive({ global: 0 });
const MyComponent = designPage(() => {
const state = reactive({ count: 0 });
const doubleCount = computed(() => state.count * 2);
onMounted(() => {
console.log('Component mounted');
});
return () => (
<div>
<p>Count: {state.count}; Double Count: {doubleCount.value}</p>
<!-- globalState.global 变更时, 所有的 MyComponent 组件都会自动更新 -->
<p>Global: {globalState.global}</p>
<button onClick={() => state.count++}>Increment</button>
</div>
);
});
const Page = designPage(() => {
watch(() => globalState.global, (newVal) => {
console.log('Global state changed:', newVal);
});
return () => (
<div>
<MyComponent />
<button onClick={() => globalState.global++}>Increment Global</button>
</div>
);
});
如上面示例所示, 由于 o2-design 的响应式功能可以自动追踪依赖, 所以不再需要复杂的状态管理功能, 组件内部直接使用 reactive 定义状态即可, 组件之间共享状态可以通过导出 reactive 对象的方式实现, 组件会自动追踪这些状态的变化并更新视图, 这也是 o2-design 组件开发的核心体验之一
v-model 由项目 Babel 插件提供语法糖,组件开发时只需要按约定提供 props + emits 即可。
更多实现细节、useModel、多字段 v-model 见 references/v-model.md。
编译后可理解为普通的 prop + update 事件 绑定:
// 编译前
<MyInput v-model={state.value} v-model-abc={state.abc} />
// 编译后(等价语义)
<MyInput modelValue={state.value} onUpdateModelValue={(v) => (state.value = v)} abc={state.abc} onUpdateAbc={(v) => (state.abc = v)} />
slots 是“父组件传内容,子组件决定放置位置”的机制, 类似 vue 中的插槽
更多信息(具名插槽、动态插槽、fallback)见 references/slots.md。
scope-slots 是“子组件在渲染插槽时给父组件传参数”的机制, 类似 vue 中的作用域插槽
详见 references/scope-slots.md
表格列 normal/edit/form/filter 插槽详见 references/column/o2-column-scope-slots.md。
也称值集、值列表, 用于将存在后端的英文数据转换成人类阅读的文本(如后端存"NEW"、"SUBMITTED"前端展示"新建"、"已提交", 其中后端存的部分叫“值”或者“编码”, 展示的值叫“含义”或“名称”, lov 的编码叫“lov 编码”或者“值集编码”或其他什么名称), 在 PC 端的“值集配置”页面配置, 使用时需要用到 O2Lov 组件或其变体, 组件会根据传入的 lovCode 自动请求后端接口, 获取“值-含义”的配置
类似 Object/Picklist, 打开一个弹框里面是一个列表, 用户可以选择其中的数据(实际工程中往往会配置一个“值字段”和“显示字段”), 与值集类似可以在 PC 端“值集视图配置”页面配置, 可以配置值集视图查询的接口、弹框标题、有哪些列等, 使用时需要用到 O2LovView 组件或其变体, 组件会根据传入的 lovCode 自动请求后端接口, 获取弹框中的列表配置, 并在用户点击后打开弹框
类似值集视图, 但是这里的弹框中的列表不是事先配置好的, 而是前端手动配置的, 使用时需要用到 O2Object 组件或其变体, 组件使用前端传入的列表配置, 适用于一些特殊的选择场景, 若无特殊需求建议优先使用 lovView 来实现选择功能
最常见的页面结构是头行结构:
List/
- index.tsx (列表页)
Detail/
- index.tsx (详情页)
- XXInfo.tsx (详情页的某个信息块, 对应头数据, 一般是页面表单拆出来的一小块, 常见的有 BaseInfo 这种)
- tabs/
- XXTab.tsx (详情页的某个 Tab 页, 对应行数据, 如订单数据关联的物流明细、客户数据关联的积分明细等)
- YYTab.tsx
实际工程中可能 .tsx 文件用的比较少, 常见的是 .js 文件(虽然内容是 jsx), 项目使用 WebPack 打包所以 .tsx 和 .js 都可以, 但不建议使用 .jsx 后缀
若无特殊说明, 所有文档都在 references 目录下
组件
references/o2-button.mdreferences/o2-input.mdreferences/o2-input-number.mdreferences/o2-currency.mdreferences/o2-select.mdreferences/o2-lov.mdreferences/o2-lov-view.mdreferences/o2-object.mdreferences/o2-switch.mdreferences/o2-datepicker.mdreferences/o2-radio.mdreferences/o2-checkbox.mdreferences/o2-address.mdreferences/o2-textarea.mdreferences/o2-textarea-input.mdreferences/o2-intl-field.mdreferences/o2-json-editor.mdreferences/o2-rich-editor.md(包含多语言富文本衍生能力说明)references/o2-upload.md(包含图片上传衍生能力说明)references/o2-form.md
references/form/o2-form-components.mdreferences/form/o2-form-layout-and-render.mdreferences/o2-form-item.mdreferences/o2-form-option.md
references/form/o2-form-option-hooks.mdreferences/form/o2-form-option-buttons.mdreferences/form/o2-form-option-multi-form.mdreferences/o2-table.md
references/o2-table-option.md
references/table/table-hooks.mdreferences/o2-column.md
references/column/o2-column-scope-slots.mdreferences/column/ 目录中(例如 references/column/o2-column-input.md)references/o2-column.md 中维护工具与问题
designComponent designPage designO2Page designKeepAlivePage 等定义页面的基础方法 references/component.md
designComponent 详解 references/design-component.md$$lov 与 useGlobalConfig 等常用工具 references/common-tools.mdreferences/o2-modal.md
references/common-pitfalls.mdreferences/validation.mdreferences/v-model.mdreferences/slots.mdreferences/scope-slots.mdo2-cli references/o2-cli.md页面模板, 若无特殊情况, 必须参照页面模板而非现有页面开发
references/page-list.mdreferences/page-detail.mdreferences/page-new.md限制: 如果要编写新页面(包括已有页面扩展子页面), 必须先读取 references/page-new.md 和 references/o2-cli.md
限制: 如果是新页面而非子页面, 没有特殊情况必须使用 o2-cli 来搭建框架, 哪怕使用的 o2-design 版本过低也是如此, 如有特殊情况必须说明清楚
tools
HZero 框架开发指南与 HZero 组件使用说明
tools
Choerodon UI 组件库开发必读
tools
link工程PC端开发说明与link-ui组件库使用说明
development
link 小程序端(使用 taro)开发必须阅读此技能