From d0c8c887fd81df716c9f76c18a000d49264982d3 Mon Sep 17 00:00:00 2001 From: Dream <1012377328@qq.com> Date: Wed, 5 Aug 2026 09:54:01 +0800 Subject: [PATCH] docs: document typed popup data contracts --- docs/src/components/common-ui/vben-drawer.md | 27 +++++++++++++++++-- docs/src/components/common-ui/vben-modal.md | 27 +++++++++++++++++-- .../demos/vben-drawer/shared-data/drawer.vue | 13 ++++++--- .../demos/vben-modal/shared-data/modal.vue | 13 ++++++--- .../en/components/common-ui/vben-drawer.md | 27 +++++++++++++++++-- .../src/en/components/common-ui/vben-modal.md | 27 +++++++++++++++++-- 6 files changed, 120 insertions(+), 14 deletions(-) diff --git a/docs/src/components/common-ui/vben-drawer.md b/docs/src/components/common-ui/vben-drawer.md index 8214b855..8f255958 100644 --- a/docs/src/components/common-ui/vben-drawer.md +++ b/docs/src/components/common-ui/vben-drawer.md @@ -50,6 +50,29 @@ Drawer 内的内容一般业务中,会比较复杂,所以我们可以将 dra +### 数据类型约束 + +推荐在 connected 子组件中声明一次数据类型并暴露 `drawerApi`,外部会从 `connectedComponent` 自动推导 `setData` 和 `getData` 的类型: + +```ts +// connected 子组件 +const [Drawer, drawerApi] = useVbenDrawer(); +defineExpose({ drawerApi }); + +// 外部组件,无需重复声明 EditData +const [Drawer, drawerApi] = useVbenDrawer({ + connectedComponent: EditDrawer, +}); +``` + +无法从组件公开实例推导时,可以显式使用 `useVbenDrawer()`。需要让多个文件共享同一契约时,可以在独立模块中预绑定: + +```ts +export const useEditDrawer = createVbenDrawer(); +``` + +三种方式的优先级为:显式泛型、connected component 自动推导、`unknown`。普通 SFC 通过 `defineExpose` 支持自动推导;泛型 SFC、函数式组件或被标注为宽 `Component` 的组件应使用显式泛型或契约工厂。`getData()` 在尚未调用 `setData()` 时返回 `undefined`,业务允许 `null`、部分对象等值时,需要在数据泛型中准确声明。 + ::: info 注意 - `VbenDrawer` 组件对于参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。 @@ -143,8 +166,8 @@ const [Drawer, drawerApi] = useVbenDrawer({ | setState | 动态设置抽屉状态属性 | `(((prev: DrawerState) => Partial)\| Partial)=>drawerApi` | | open | 打开弹窗 | `()=>void` | --- | | close | 关闭弹窗 | `()=>void` | --- | -| setData | 设置共享数据 | `(data:T)=>drawerApi` | --- | -| getData | 获取共享数据 | `()=>T` | --- | +| setData | 设置共享数据 | `(data:TData)=>drawerApi` | --- | +| getData | 获取共享数据 | `()=>TData\|undefined` | --- | | useStore | 获取可响应式状态 | - | --- | | lock | 将抽屉标记为提交中,锁定当前状态 | `(isLock:boolean)=>drawerApi` | >5.5.3 | | unlock | lock方法的反操作,解除抽屉的锁定状态,也是lock(false)的别名 | `()=>drawerApi` | >5.5.3 | diff --git a/docs/src/components/common-ui/vben-modal.md b/docs/src/components/common-ui/vben-modal.md index 65c2912d..29d7fee7 100644 --- a/docs/src/components/common-ui/vben-modal.md +++ b/docs/src/components/common-ui/vben-modal.md @@ -56,6 +56,29 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda +### 数据类型约束 + +推荐在 connected 子组件中声明一次数据类型并暴露 `modalApi`,外部会从 `connectedComponent` 自动推导 `setData` 和 `getData` 的类型: + +```ts +// connected 子组件 +const [Modal, modalApi] = useVbenModal(); +defineExpose({ modalApi }); + +// 外部组件,无需重复声明 EditData +const [Modal, modalApi] = useVbenModal({ + connectedComponent: EditModal, +}); +``` + +无法从组件公开实例推导时,可以显式使用 `useVbenModal()`。需要让多个文件共享同一契约时,可以在独立模块中预绑定: + +```ts +export const useEditModal = createVbenModal(); +``` + +三种方式的优先级为:显式泛型、connected component 自动推导、`unknown`。普通 SFC 通过 `defineExpose` 支持自动推导;泛型 SFC、函数式组件或被标注为宽 `Component` 的组件应使用显式泛型或契约工厂。`getData()` 在尚未调用 `setData()` 时返回 `undefined`,业务允许 `null`、部分对象等值时,需要在数据泛型中准确声明。 + ## 动画类型 通过 `animationType` 属性可以控制弹窗的动画效果: @@ -162,8 +185,8 @@ const [Modal, modalApi] = useVbenModal({ | setState | 动态设置弹窗状态属性 | `(((prev: ModalState) => Partial)\| Partial)=>modalApi` | - | | open | 打开弹窗 | `()=>void` | - | | close | 关闭弹窗 | `()=>void` | - | -| setData | 设置共享数据 | `(data:T)=>modalApi` | - | -| getData | 获取共享数据 | `()=>T` | - | +| setData | 设置共享数据 | `(data:TData)=>modalApi` | - | +| getData | 获取共享数据 | `()=>TData\|undefined` | - | | useStore | 获取可响应式状态 | - | - | | lock | 将弹窗标记为提交中,锁定当前状态 | `(isLock:boolean)=>modalApi` | >5.5.2 | | unlock | lock方法的反操作,解除弹窗的锁定状态,也是lock(false)的别名 | `()=>modalApi` | >5.5.3 | diff --git a/docs/src/demos/vben-drawer/shared-data/drawer.vue b/docs/src/demos/vben-drawer/shared-data/drawer.vue index 629199b6..0cd9707b 100644 --- a/docs/src/demos/vben-drawer/shared-data/drawer.vue +++ b/docs/src/demos/vben-drawer/shared-data/drawer.vue @@ -3,9 +3,14 @@ import { ref } from 'vue'; import { useVbenDrawer } from '@vben/common-ui'; -const data = ref(); +interface SharedData { + content: string; + payload: string; +} -const [Drawer, drawerApi] = useVbenDrawer({ +const data = ref(); + +const [Drawer, drawerApi] = useVbenDrawer({ onCancel() { drawerApi.close(); }, @@ -14,10 +19,12 @@ const [Drawer, drawerApi] = useVbenDrawer({ }, onOpenChange(isOpen: boolean) { if (isOpen) { - data.value = drawerApi.getData>(); + data.value = drawerApi.getData(); } }, }); + +defineExpose({ drawerApi });