综合案例:用户域 CRUD + 审批
把前面几篇里分散的能力串进一个中后台场景:新建 / 编辑 / 详情 / 审批。约定见 最佳实践;对照可看:内容与容器拆分、LayerTemplate 投递、defineLayer / closeOn、按场景拆实例;异步用 vue-asyncx。
本例要点:
- 业务收在内容里:API、校验、
closeOn、操作按钮;列表只听*Done刷新 - 壳统一
action:BaseDialog底栏(自带取消 + 业务按钮),BaseDrawer标题右侧;内容一律LayerTemplate name="action"。详情view仍投递带 tooltip 的警告图标,与壳上「取消」并存——内容补充外壳,不覆盖。 - 离开确认走壳
beforeClose:UserForm在defineLayer里透传 ElDialog 的beforeClose(脏数据二次确认)。BaseDialog的「取消」调用handleClose(),与点 X / 遮罩同一条路,才会进该钩子——不要直接emit(false)绕过。成功保存仍是内容emit+closeOn,不经beforeClose;不想关就别emit。 - 按场景拆实例(本例):
userCreate/userEdit/userDetail/userAudit,mode与回调写在use第二参。实际项目也可以只用一个UserForm实例,在open时传入mode。 - 审批可页内复用:
UserAudit的action加visible-outside(同款操作区多一个落点);「平铺审核」直接嵌组件,不经 Drawer。页内 / 弹层外壳不同时见上一篇 页内与弹层共用操作区。
vue
<LayerTemplate :to="layer" name="action">…</LayerTemplate>加载示例中…
为什么这样拆
按领域边界分文件 / 实例,而不是按「是不是弹窗」:
- 用户资料(同一领域):新增、编辑、详情都是同一份用户数据与表单,收在
UserForm,用mode区分可写 / 只读即可。 - 审批(另一领域):通过 / 驳回、二次确认、结果态是审批流程,不是表单保存的变体,所以另起
UserAudit(可嵌套只读UserForm看字段),而不是给表单再加mode: 'audit'。 - 列表(页面领域):
App只维护自己的列表;不关心弹层里怎么调 API,只在createDone/updateDone/auditDone等事件后queryUsers()刷新自身。
本例弹层实例按场景拆开(userCreate / userEdit / userDetail / userAudit),和上面的领域划分一致;合并为更少实例也可以。
结构
| 内容 | 职责 | 容器 |
|---|---|---|
UserForm | create / edit / view(只读)、API、closeOn、action | Dialog |
UserAudit | 嵌套 UserForm mode="view";驳回/通过与结果态 | Drawer,或页内平铺 |
App | 列表展示;on*Done → 刷新;可选嵌 UserAudit | — |
审核接口成功即 auditDone(列表刷新);弹层内点「完成」再 finish 关层。页内平铺同样走 finish,由页面自行决定是否重置/卸卡。UserAudit 里嵌套的 UserForm 只当普通只读表单用。