From eec6f41f6aff3bbe06156a6ddfa8b05ff77c0844 Mon Sep 17 00:00:00 2001 From: Netfan Date: Wed, 11 Dec 2024 10:45:04 +0800 Subject: [PATCH] refactor: `ApiComponent` with docs (#5099) * refactor: `ApiComponent` with docs * docs: remove invalid docs * docs: remove duplicate prop docs * docs: update `ApiComponent` docs --- apps/web-antd/src/adapter/component/index.ts | 6 +- apps/web-ele/src/adapter/component/index.ts | 6 +- apps/web-naive/src/adapter/component/index.ts | 6 +- docs/.vitepress/config/zh.mts | 4 + .../common-ui/vben-api-component.md | 150 ++++++++++++++++++ .../vben-api-component/cascader/index.vue | 100 ++++++++++++ .../api-component.vue} | 6 +- .../src/components/api-component/index.ts | 1 + .../src/components/api-select/index.ts | 1 - .../effects/common-ui/src/components/index.ts | 2 +- playground/src/adapter/component/index.ts | 6 +- 11 files changed, 271 insertions(+), 17 deletions(-) create mode 100644 docs/src/components/common-ui/vben-api-component.md create mode 100644 docs/src/demos/vben-api-component/cascader/index.vue rename packages/effects/common-ui/src/components/{api-select/api-select.vue => api-component/api-component.vue} (97%) create mode 100644 packages/effects/common-ui/src/components/api-component/index.ts delete mode 100644 packages/effects/common-ui/src/components/api-select/index.ts diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts index aa96740d..a43a8280 100644 --- a/apps/web-antd/src/adapter/component/index.ts +++ b/apps/web-antd/src/adapter/component/index.ts @@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui'; import type { Component, SetupContext } from 'vue'; import { h } from 'vue'; -import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui'; +import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; import { @@ -82,7 +82,7 @@ async function initComponentAdapter() { // import('xxx').then((res) => res.Button), ApiSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, @@ -97,7 +97,7 @@ async function initComponentAdapter() { }, ApiTreeSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, diff --git a/apps/web-ele/src/adapter/component/index.ts b/apps/web-ele/src/adapter/component/index.ts index 6c8667cd..818c8c4e 100644 --- a/apps/web-ele/src/adapter/component/index.ts +++ b/apps/web-ele/src/adapter/component/index.ts @@ -9,7 +9,7 @@ import type { Recordable } from '@vben/types'; import type { Component, SetupContext } from 'vue'; import { h } from 'vue'; -import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui'; +import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; import { @@ -70,7 +70,7 @@ async function initComponentAdapter() { // import('xxx').then((res) => res.Button), ApiSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, @@ -84,7 +84,7 @@ async function initComponentAdapter() { }, ApiTreeSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, diff --git a/apps/web-naive/src/adapter/component/index.ts b/apps/web-naive/src/adapter/component/index.ts index aed92b73..545a6199 100644 --- a/apps/web-naive/src/adapter/component/index.ts +++ b/apps/web-naive/src/adapter/component/index.ts @@ -8,7 +8,7 @@ import type { BaseFormComponentType } from '@vben/common-ui'; import type { Component, SetupContext } from 'vue'; import { h } from 'vue'; -import { ApiSelect, globalShareState, IconPicker } from '@vben/common-ui'; +import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; import { @@ -70,7 +70,7 @@ async function initComponentAdapter() { ApiSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, @@ -83,7 +83,7 @@ async function initComponentAdapter() { }, ApiTreeSelect: (props, { attrs, slots }) => { return h( - ApiSelect, + ApiComponent, { placeholder: $t('ui.placeholder.select'), ...props, diff --git a/docs/.vitepress/config/zh.mts b/docs/.vitepress/config/zh.mts index 27fb96c0..25e93ced 100644 --- a/docs/.vitepress/config/zh.mts +++ b/docs/.vitepress/config/zh.mts @@ -162,6 +162,10 @@ function sidebarComponents(): DefaultTheme.SidebarItem[] { collapsed: false, text: '通用组件', items: [ + { + link: 'common-ui/vben-api-component', + text: 'ApiComponent Api组件包装器', + }, { link: 'common-ui/vben-modal', text: 'Modal 模态框', diff --git a/docs/src/components/common-ui/vben-api-component.md b/docs/src/components/common-ui/vben-api-component.md new file mode 100644 index 00000000..f9db74e4 --- /dev/null +++ b/docs/src/components/common-ui/vben-api-component.md @@ -0,0 +1,150 @@ +--- +outline: deep +--- + +# Vben ApiComponent Api组件包装器 + +框架提供的API“包装器”,它一般不独立使用,主要用于包装其它组件,为目标组件提供自动获取远程数据的能力,但仍然保持了目标组件的原始用法。 + +::: info 写在前面 + +我们在各个应用的组件适配器中,使用ApiComponent包装了Select、TreeSelect组件,使得这些组件可以自动获取远程数据并生成选项。其它类似的组件(比如Cascader)如有需要也可以参考示例代码自行进行包装。 + +::: + +## 基础用法 + +通过 `component` 传入其它组件的定义,并配置相关的其它属性(主要是一些名称映射)。包装组件将通过`api`获取数据(`beforerFetch`、`afterFetch`将分别在`api`运行前、运行后被调用),使用`resultField`从中提取数组,使用`valueField`、`labelField`等来从数据中提取value和label(如果提供了`childrenField`,会将其作为树形结构递归处理每一级数据),之后将处理好的数据通过`optionsPropName`指定的属性传递给目标组件。 + +::: details 包装级联选择器,点击下拉时开始加载远程数据 + +```vue + + +``` + +::: + +### Props + +| 属性名 | 描述 | 类型 | 默认值 | +| --- | --- | --- | --- | +| component | 欲包装的组件 | `Component` | - | +| numberToString | 是否将value从数字转为string | `boolean` | `false` | +| api | 获取数据的函数 | `(arg?: any) => Promise>` | - | +| params | 传递给api的参数 | `Record` | - | +| resultField | 从api返回的结果中提取options数组的字段名 | `string` | - | +| labelField | label字段名 | `string` | `label` | +| childrenField | 子级数据字段名,需要层级数据的组件可用 | `string` | `` | +| valueField | value字段名 | `string` | `value` | +| optionsPropName | 组件接收options数据的属性名称 | `string` | `options` | +| modelPropName | 组件的双向绑定属性名,默认为modelValue。部分组件可能为value | `string` | `modelValue` | +| immediate | 是否立即调用api | `boolean` | `true` | +| alwaysLoad | 每次`visibleEvent`事件发生时都重新请求数据 | `boolean` | `false` | +| beforeFetch | 在api请求之前的回调函数 | `AnyPromiseFunction` | - | +| afterFetch | 在api请求之后的回调函数 | `AnyPromiseFunction` | - | +| options | 直接传入选项数据,也作为api返回空数据时的后备数据 | `OptionsItem[]` | - | +| visibleEvent | 触发重新请求数据的事件名 | `string` | - | +| loadingSlot | 组件的插槽名称,用来显示一个"加载中"的图标 | `string` | - | + +``` + +``` diff --git a/docs/src/demos/vben-api-component/cascader/index.vue b/docs/src/demos/vben-api-component/cascader/index.vue new file mode 100644 index 00000000..957964cd --- /dev/null +++ b/docs/src/demos/vben-api-component/cascader/index.vue @@ -0,0 +1,100 @@ + + diff --git a/packages/effects/common-ui/src/components/api-select/api-select.vue b/packages/effects/common-ui/src/components/api-component/api-component.vue similarity index 97% rename from packages/effects/common-ui/src/components/api-select/api-select.vue rename to packages/effects/common-ui/src/components/api-component/api-component.vue index 71e1f125..d1d42ad7 100644 --- a/packages/effects/common-ui/src/components/api-select/api-select.vue +++ b/packages/effects/common-ui/src/components/api-component/api-component.vue @@ -1,7 +1,7 @@