vue-vben-admin 的弹窗和表单为什么不用传一堆 prop:3 个设计决策
vue-vben-admin 的弹窗和表单为什么不用传一堆 prop3 个设计决策【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin打开弹窗、填一张表单、提交时按钮转圈、结束后弹窗关闭——这条状态链如果靠自己维护至少是一二十行 ref 加 watch。vue-vben-admin基于 Vue3、Vite、TypeScript、Shadcn UI 构建的中后台管理系统里整条链路只剩几行回调。它不靠什么魔法就靠一个贯穿始终的设计交互组件都以组件 api 对象的形式交付。它是什么不是一个组件库而是一个状态管理器先说清定位vue-vben-admin 不是组件库是一套开箱即用的中后台系统登录页、权限、菜单全都有。它和常见 Element/Ant Design 脚手架的区别在于那些给的是 UI 组件vben 把状态当一等公民——Modal、Form 这类交互组件都附带一个可以直接从代码调用的 api 对象UI 只是这个对象的视觉投影。让 Modal 和 Form 不打架的 3 个机制1. 看清 useVbenModal 返回的东西最反直觉的一点useVbenModal的返回值是一个元组不是一个组件。// packages/core/ui-kit/popup-ui/src/modal/use-modal.ts节选 const api new ModalApiTResolvedData(mergedOptions); // 这里的组件只是个函数组件壳唯一职责是把 api // 塞进渲染参数交给真正的 Modal 去画 const Modal defineComponent((props, { attrs, slots }) { return () h(VbenModal, { ...props, ...attrs, modalApi: api }, slots); }); return [Modal, api] as const; // 组件负责渲染api 负责状态组件是易耗品api 才是持久物开关、注入数据全不需要组件 ref直接调 api。对日常开发意味着什么弹窗状态不再挂在组件实例上把弹窗抽成独立文件也不会断。2. 把状态塞进小 Store让 UI 订阅变化第二个决策更进一步Modal 连 isOpen 都不存在组件里而是放进一个 Store仓库内实现的小型状态容器可以理解为迷你版 PiniaUI 只是订阅者。// packages/core/ui-kit/popup-ui/src/modal/modal-api.ts节选 this.store new StoreModalState({ ...defaultState, ...storeState }); this.store.subscribe((state) { const prevIsOpen this.state?.isOpen; this.state state; // isOpen 翻转是唯一事件源生命周期钩子全从这里驱动 if (state?.isOpen ! prevIsOpen) this.api.onOpenChange?.(!!state.isOpen); });open() 只是setState({ isOpen: true })按钮 loading、遮罩显隐都是派生态。日常开发意味着什么想加每次打开都重置这类钩子只在订阅里加一行完全不用碰组件。3. 用 setData/getData 打通数据通道第三个决策解决数据怎么进弹窗。ModalApi 有一块 sharedData类型由泛型约束传错数据编译期就会报错// packages/core/ui-kit/popup-ui/src/modal/modal-api.ts节选 public sharedData { payload: undefined as TData | undefined }; setData(payload: TData) { this.sharedData.payload payload; return this; // 返回 this是为了能写成 setData(...).open() 链式调用 } getData() { return this.sharedData.payload; }给编辑弹窗递一行数据写setData(row).open()就行不必再维护一个 ref 传值。落地5 行代码接上弹窗 表单最常见的业务场景就是开弹窗、填表单、提交、关。官方示例在playground/src/views/examples/modal/form-modal-demo.vue关键只有 onOpenChange 和 onConfirm 两个钩子script setup langts const [Form, formApi] useVbenForm({ schema: [{ component: Input, fieldName: name, label: 姓名, rules: required }], }); // 数据契约声明弹窗收什么数据TS 直接帮你检查 const [Modal, modalApi] useVbenModal{ values?: Recordstring, unknown }({ // 表单赋值只有一个时机弹窗打开时把注入的数据拉出来 onOpenChange: (open) open formApi.setValues(modalApi.getData()?.values ?? {}), onConfirm: () formApi.validateAndSubmit(), // 先校验再触发表单提交 }); function edit(row: Recordstring, unknown) { modalApi.setData({ values: row }).open(); // 先递数据再打开 } /script template ModalForm //Modal /template模板部分就一行ModalForm //Modal其余交互全在 api 对象里完成。⚠️ 上手前绕开的 3 个坑现象弹窗开了表单是空的。原因先 open() 再 setData()或者试图用 props 传值。解法固定setData(...).open()顺序在 onOpenChange 里读 getData() 写入表单。现象点了确定用户还能手动关掉弹窗造成二次提交或状态丢失。原因onConfirm 是异步请求但弹窗没锁定关闭按钮仍可点。解法onConfirm 开头调modalApi.lock()它会自动隐藏关闭键、禁用取消、把确认键置为 loading请求完解锁。现象弹窗抽成独立组件文件后两边各调一次 useVbenModal出现两套状态外层 open() 无效。原因外部连接没走 connectedComponent 机制。解法外层把组件传进useVbenModal({ connectedComponent: 弹窗组件 })内部经 provide/inject 接通 api源码里 checkProps 还会直接告警存在 connectedComponent 时不要往模板上直接传 props。一句话设计哲学与源码入口一句话组件只是投影API 才是真相——所有状态变更都走 api 对象UI 只负责渲染。想继续深挖两个入口就够弹窗与抽屉源码在packages/core/ui-kit/popup-ui/表单源码在packages/core/ui-kit/form-ui/完整用法套路看playground/src/views/examples/modal/。【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考