微信小程序:把完整组件树接到 XML
开始本章前,Web 端应当已经完成 Group + Todo + Upsert。小程序不是重新写 CRUD,而是为同一组 OakComponent 增加 index.xml、index.less 和 index.config.ts。
1. 添加 workspace
npx oak-cli add mp wechatMp
npm install
生成脚本后可以运行:
npm run start:mp:wechatMp
npm run build:mp:wechatMp
2. 保持同一棵节点树
frontend/home Group ListNode
└── <group-panel oakPath="...groupId">
└── <todo-list oakPath="...todo$group">
└── <todo-upsert oakPath="...todoId">
小程序页面仍然复用 Web 已写好的 index.ts。只为事件对象增加窄类型适配,例如:
type MpDatasetEvent = {
currentTarget: {
dataset: {
id?: string;
};
};
};
不要使用 any 接收小程序事件。
3. 配置页面组件
在 frontend/home/index.config.ts 的 mp 中声明:
mp: {
navigationBarTitleText: '任务清单',
enablePullDownRefresh: false,
usingComponents: {
'group-panel': '../../../components/group/panel/index',
'group-upsert': '../../../components/group/upsert/index',
},
},
组件自己的配置使用 CreateComponentConfig:
import { CreateComponentConfig } from '@oak-frontend-base/config';
export default CreateComponentConfig({
mp: {
usingComponents: {
'todo-list': '../../todo/list/index',
},
},
});
不要手改生成后的页面 JSON。
4. 首页 tabs 与 Group Modal
核心 XML:
<scroll-view scroll-x="{{true}}">
<button
wx:for="{{groups}}"
wx:key="id"
data-id="{{item.id}}"
bindtap="selectGroupFromMp"
>
{{item.name || t('unnamedGroup')}}
</button>
</scroll-view>
<group-panel
wx:if="{{selectedGroupId && !editingGroupId}}"
oakPath="{{oakFullpath + '.' + selectedGroupId}}"
/>
<view wx:if="{{editingGroupId}}" class="modalMask">
<group-upsert oakPath="{{oakFullpath + '.' + editingGroupId}}" />
<button bindtap="cancelGroupFromMp">{{t('cancel')}}</button>
<button bindtap="saveGroupFromMp">{{t('save')}}</button>
</view>
selectedGroupId、editingGroupId 必须在 data 中预声明。XML 检查不会接受模板中凭空出现的字段。
5. Upsert XML
Group Upsert 的 index.ts 同时声明初始 data 和 formData:
data: {
name: '',
},
formData({ data }) {
return { name: data?.name || '' };
},
XML:
<input
value="{{name}}"
placeholder="请输入分组名称"
bindinput="setNameFromMp"
/>
Todo Upsert 同理声明 title 和 completed,再使用 <input> 与 <switch>。
6. Todo 关系列表
GroupPanel:
<todo-list oakPath="{{oakFullpath + '.todo$group'}}" />
TodoList 新增后挂 Upsert:
<todo-upsert
wx:if="{{editingTodoId}}"
oakPath="{{oakFullpath + '.' + editingTodoId}}"
/>
保存仍调用共享的 saveTodo(),由它执行父 Group path。小程序端不要另外手工拼 groupId。
7. 构建检查
npm run build
npm run build:mp:wechatMp
目标输出应包含:
[oak-xml-check] ... 0 XML diagnostics, 0 TypeScript diagnostics
0 个提示
重点处理:
OAK_MP_XML_UNDECLARED_DATA:字段没有在data/properties/formData合同中声明;- 组件属性不存在:检查
usingComponents指向的真实 OakComponent 及其properties; - 事件不存在:检查 XML 的
bind*名称是否与methods一致; oakPath拼错:检查最终树路径,尤其是todo$group。
8. 验证清单
在微信开发者工具中逐项验证:
- 新增 Group 并重进页面;
- tabs 切换后 Todo 相互隔离;
- 新增 Todo 后数据库得到正确
groupId; - 编辑、完成切换、删除均持久化;
- 取消 Modal 不产生记录。
完成后提交:
git add .
git commit -m "feat: add grouped Todo mini-program UI"