docs(@vben/docs): sync component docs with current APIs

This commit is contained in:
xingyu4j
2026-03-14 21:34:48 +08:00
parent 6c274b75b8
commit 6b3bcee582
21 changed files with 937 additions and 283 deletions

View File

@@ -42,6 +42,10 @@ export const en = defineConfig({
base: '/en/commercial/',
items: sidebarCommercial(),
},
'/en/components/': {
base: '/en/components/',
items: sidebarComponents(),
},
'/en/guide/': { base: '/en/guide/', items: sidebarGuide() },
},
},
@@ -63,6 +67,11 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] {
},
{ link: 'introduction/quick-start', text: 'Quick Start' },
{ link: 'introduction/thin', text: 'Lite Version' },
{
base: '/',
link: 'components/introduction',
text: 'Components',
},
],
},
{
@@ -132,6 +141,68 @@ function sidebarCommercial(): DefaultTheme.SidebarItem[] {
];
}
function sidebarComponents(): DefaultTheme.SidebarItem[] {
return [
{
text: 'Components',
items: [
{
link: 'introduction',
text: 'Introduction',
},
],
},
{
collapsed: false,
text: 'Layout UI',
items: [
{
link: 'layout-ui/page',
text: 'Page',
},
],
},
{
collapsed: false,
text: 'Common UI',
items: [
{
link: 'common-ui/vben-api-component',
text: 'ApiComponent',
},
{
link: 'common-ui/vben-alert',
text: 'Alert',
},
{
link: 'common-ui/vben-modal',
text: 'Modal',
},
{
link: 'common-ui/vben-drawer',
text: 'Drawer',
},
{
link: 'common-ui/vben-form',
text: 'Form',
},
{
link: 'common-ui/vben-vxe-table',
text: 'Vxe Table',
},
{
link: 'common-ui/vben-count-to-animator',
text: 'CountToAnimator',
},
{
link: 'common-ui/vben-ellipsis-text',
text: 'EllipsisText',
},
],
},
];
}
function nav(): DefaultTheme.NavItem[] {
return [
{
@@ -143,11 +214,11 @@ function nav(): DefaultTheme.NavItem[] {
link: '/en/guide/introduction/vben',
text: 'Guide',
},
// {
// activeMatch: '^/en/components/',
// link: '/en/components/introduction',
// text: 'Components',
// },
{
activeMatch: '^/en/components/',
link: '/en/components/introduction',
text: 'Components',
},
{
text: 'Historical Versions',
items: [

View File

@@ -10,7 +10,9 @@ import { $t } from '@vben/locales';
import { initComponentAdapter } from './component';
// oxlint-disable-next-line typescript/no-floating-promises
initComponentAdapter();
setupVbenForm<ComponentType>({
config: {
baseModelPropName: 'value',

View File

@@ -4,132 +4,90 @@ outline: deep
# Vben Alert 轻量提示框
框架提供的一些用于轻量提示的弹窗仅使用js代码即可快速动态创建提示而不需要在template写任何代码
`Alert` 提供了一组纯 JavaScript 调用的轻量提示框能力,适合快速创建 `alert``confirm``prompt` 这类简单交互
::: info 用场景
::: info 用场景
Alert提供的功能与Modal类似但只适用于简单应用场景。例如临时性、动态地弹出模态确认框、输入框等。如果对弹窗有更复杂的需求请使用VbenModal
:::
`Alert``Modal` 的能力有部分重叠,但更适合临时确认、简单提示和轻量输入场景。复杂弹窗仍然建议使用 `Vben Modal`。:::
::: tip 注意
Alert提供的快捷方法alert、confirmprompt动态创建的弹窗在已打开的情况下不支持HMR热更新),代码变更后需要关闭这些弹窗后重新打开。
:::
::: tip README
下方示例代码中的,存在一些主题色未适配、样式缺失的问题,这些问题只在文档内会出现,实际使用并不会有这些问题,可忽略,不必纠结。
:::
通过 `alert``confirm``prompt` 动态创建的弹窗在已打开的情况下不支持 HMR 热更新。修改相关代码后,需要关闭后重新打开。:::
## 基础用法
使用 `alert` 创建只有一个确认按钮的提示框。
使用 `alert` 创建只有确认按钮的提示框。
<DemoPreview dir="demos/vben-alert/alert" />
使用 `confirm` 创建确认和取消按钮的提示框。
使用 `confirm` 创建确认和取消按钮的提示框。
<DemoPreview dir="demos/vben-alert/confirm" />
使用 `prompt` 创建有确认和取消按钮、接受用户输入的提示框。
使用 `prompt` 创建可接收用户输入的提示框。
<DemoPreview dir="demos/vben-alert/prompt" />
## useAlertContext
弹窗的contentfooter、icon使用自定义组件时,在这些组件中可以使用 `useAlertContext` 获取当前弹窗上下文对象,用来主动控制弹窗
`content``footer``icon` 使用的是自定义组件时,可以在这些组件内部通过 `useAlertContext()` 获取当前弹窗上下文,并主动触发确认或取消
::: tip 注意
`useAlertContext`只能在setup或函数式组件中
:::
`useAlertContext` 只能在 `setup` 或函数式组件中使用。:::
### Methods
| 方法 | 描述 | 类型 | 版本要求 |
| --------- | ------------------ | -------- | -------- |
| doConfirm | 调用弹窗的确认操作 | ()=>void | >5.5.4 |
| doCancel | 调用弹窗的取消操作 | ()=>void | >5.5.4 |
| 方法 | 描述 | 类型 | 版本要求 |
| --------- | ---------------------- | ------------ | -------- |
| doConfirm | 触发当前弹窗的确认操作 | `() => void` | `>5.5.4` |
| doCancel | 触发当前弹窗的取消操作 | `() => void` | `>5.5.4` |
## 类型说明
```ts
/** 预置的图标类型 */
export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
export type BeforeCloseScope = {
/** 是否为点击确认按钮触发的关闭 */
isConfirm: boolean;
};
/**
* alert 属性
*/
export type AlertProps = {
/** 关闭前的回调如果返回false则终止关闭 */
beforeClose?: (
scope: BeforeCloseScope,
) => boolean | Promise<boolean | undefined> | undefined;
/** 边框 */
bordered?: boolean;
/** 按钮对齐方式 */
buttonAlign?: 'center' | 'end' | 'start';
/** 取消按钮的标题 */
cancelText?: string;
/** 是否居中显示 */
centered?: boolean;
/** 确认按钮的标题 */
confirmText?: string;
/** 弹窗容器的额外样式 */
containerClass?: string;
/** 弹窗提示内容 */
content: Component | string;
/** 弹窗内容的额外样式 */
contentClass?: string;
/** 执行beforeClose回调期间在内容区域显示一个loading遮罩*/
contentMasking?: boolean;
/** 弹窗底部内容(与按钮在同一个容器中) */
footer?: Component | string;
/** 弹窗的图标(在标题的前面) */
icon?: Component | IconType;
/**
* 弹窗遮罩模糊效果
*/
overlayBlur?: number;
/** 是否显示取消按钮 */
showCancel?: boolean;
/** 弹窗标题 */
title?: string;
};
/** prompt 属性 */
export type PromptProps<T = any> = {
/** 关闭前的回调如果返回false则终止关闭 */
beforeClose?: (scope: {
isConfirm: boolean;
value: T | undefined;
}) => boolean | Promise<boolean | undefined> | undefined;
/** 用于接受用户输入的组件 */
component?: Component;
/** 输入组件的属性 */
componentProps?: Recordable<any>;
/** 输入组件的插槽 */
componentSlots?: Recordable<Component>;
/** 默认值 */
componentSlots?:
| (() => any)
| Recordable<unknown>
| VNode
| VNodeArrayChildren;
defaultValue?: T;
/** 输入组件的值属性名 */
modelPropName?: string;
} & Omit<AlertProps, 'beforeClose'>;
/**
* 函数签名
* alert和confirm的函数签名相同。
* confirm默认会显示取消按钮而alert默认只有一个按钮
* */
export function alert(options: AlertProps): Promise<void>;
export function alert(
message: string,
@@ -141,19 +99,10 @@ export function alert(
options?: Partial<AlertProps>,
): Promise<void>;
/**
* 弹出输入框的函数签名。
* beforeClose的参数会传入用户当前输入的值
* component指定接受用户输入的组件默认为Input
* componentProps 为输入组件设置的属性数据
* defaultValue 默认的值
* modelPropName 输入组件的值属性名称。默认为modelValue
*/
export async function prompt<T = any>(
options: Omit<AlertProps, 'beforeClose'> & {
beforeClose?: (
scope: BeforeCloseScope & {
/** 输入组件的当前值 */
value: T;
},
) => boolean | Promise<boolean | undefined> | undefined;

View File

@@ -14,7 +14,7 @@ outline: deep
## 基础用法
通过 `component` 传入其它组件的定义,并配置相关的其它属性(主要是一些名称映射)。包装组件将通过`api`获取数据(`beforerFetch``afterFetch`将分别在`api`运行前、运行后被调用),使用`resultField`从中提取数组,使用`valueField``labelField`等来从数据中提取valuelabel如果提供了`childrenField`,会将其作为树形结构递归处理每一级数据),之后将处理好的数据通过`optionsPropName`指定的属性传递给目标组件。
通过 `component` 传入其它组件的定义,并配置相关的其它属性(主要是一些名称映射)。包装组件将通过 `api` 获取数据(`beforeFetch``afterFetch` 将分别在 `api` 运行前、运行后被调用),使用 `resultField` 从中提取数组,使用 `valueField``labelField` 等来从数据中提取 valuelabel如果提供了 `childrenField`,会将其作为树形结构递归处理每一级数据),之后将处理好的数据通过 `optionsPropName` 指定的属性传递给目标组件。
::: details 包装级联选择器,点击下拉时开始加载远程数据

View File

@@ -4,56 +4,54 @@ outline: deep
# Vben CountToAnimator 数字动画
框架提供的数字动画组件,支持数字动画效果。
`CountToAnimator` 用于展示数字滚动动画效果。
> 如果文档内没有参数说明,可以尝试在在线示例内寻找
> 如果文档内没有覆盖到你需要的细节,可以结合在线示例一起查看。
::: info 写在前面
如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。
:::
这是一个轻量数字动画组件。如果你需要完全不同的过渡控制方式,也可以直接使用原生动画方案或自行封装。:::
## 基础用法
通过 `start-val``end-val`设置数字动画的始值和结束值, 持续时间`3000`ms
通过 `start-val``end-val` 设置数字动画的始值和结束值,配合 `duration` 控制动画时长
<DemoPreview dir="demos/vben-count-to-animator/basic" />
## 自定义前缀分隔符
## 自定义前缀分隔符
通过 `prefix``separator` 设置数字动画的前缀和分隔符
通过 `prefix``suffix``separator` `decimal` 可以控制展示格式
<DemoPreview dir="demos/vben-count-to-animator/custom" />
### Props
| 属性名 | 描述 | 类型 | 默认值 |
| ---------- | -------------- | --------- | -------- |
| startVal | 起始值 | `number` | `0` |
| endVal | 结束值 | `number` | `2021` |
| duration | 动画持续时间 | `number` | `1500` |
| autoplay | 自动执行 | `boolean` | `true` |
| prefix | 前缀 | `string` | - |
| suffix | 后缀 | `string` | - |
| separator | 分隔符 | `string` | `,` |
| color | 字体颜色 | `string` | - |
| useEasing | 是否开启动画 | `boolean` | `true` |
| transition | 动画效果 | `string` | `linear` |
| decimals | 保留小数点位数 | `number` | `0` |
| 属性名 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| startVal | 起始值 | `number` | `0` |
| endVal | 结束值 | `number` | `2021` |
| duration | 动画持续时间 | `number` | `1500` |
| autoplay | 是否自动播放 | `boolean` | `true` |
| prefix | 前缀 | `string` | `''` |
| suffix | 后缀 | `string` | `''` |
| separator | 千分位分隔符 | `string` | `','` |
| decimal | 小数点分隔符 | `string` | `'.'` |
| color | 文本颜色 | `string` | `''` |
| useEasing | 是否启用过渡预设 | `boolean` | `true` |
| transition | 过渡预设名称 | `keyof typeof TransitionPresets` | `'linear'` |
| decimals | 保留小数位数 | `number` | `0` |
### Events
| 事件名 | 描述 | 类型 |
| -------------- | -------------- | -------------- |
| started | 动画开始 | `()=>void` |
| finished | 动画结束 | `()=>void` |
| ~~onStarted~~ | ~~动画已开始~~ | ~~`()=>void`~~ |
| ~~onFinished~~ | ~~动画已结束~~ | ~~`()=>void`~~ |
| 事件名 | 描述 | 类型 |
| -------------- | ----------------------------- | ---------------- |
| started | 动画开始时触发 | `() => void` |
| finished | 动画结束时触发 | `() => void` |
| ~~onStarted~~ | ~~已废弃,请改用 `started`~~ | ~~`() => void`~~ |
| ~~onFinished~~ | ~~已废弃,请改用 `finished`~~ | ~~`() => void`~~ |
### Methods
| 方法名 | 描述 | 类型 |
| ------ | ------------ | ---------- |
| start | 开始执行动画 | `()=>void` |
| reset | 重置 | `()=>void` |
| 方法名 | 描述 | 类型 |
| ------ | -------------------------------- | ------------ |
| reset | 重置为 `startVal` 并重新执行动画 | `() => void` |

View File

@@ -55,7 +55,7 @@ Drawer 内的内容一般业务中,会比较复杂,所以我们可以将 dra
- `VbenDrawer` 组件对于参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenDrawer参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。
- 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenDrawer`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。
- 使用了`connectedComponent`参数时,可以配置`destroyOnClose`属性来决定当关闭弹窗时,是否要销毁`connectedComponent`组件(重新创建`connectedComponent`组件,这将会把其内部所有的变量、状态、数据等恢复到初始状态。)。
- 如果抽屉的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultDrawerProps`的参数来设置默认属性,如默认隐藏全屏按钮修改默认ZIndex等。
- 如果抽屉的默认行为不符合你的预期,可以在对应应用的 `apps/<app>/src/bootstrap.ts` 中修改 `setDefaultDrawerProps` 的参数来设置默认属性,例如修改默认 `zIndex` 等。
:::
@@ -116,7 +116,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
| 事件名 | 描述 | 类型 | 版本限制 |
| --- | --- | --- | --- |
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | --- |
| onBeforeClose | 关闭前触发,返回 `false` 或 Promise reject 则禁止关闭 | `()=>Promise<boolean \| undefined>\|boolean\|undefined` | >5.5.2 支持 Promise |
| onCancel | 点击取消按钮触发 | `()=>void` | --- |
| onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.5.2 |
| onConfirm | 点击确认按钮触发 | `()=>void` | --- |
@@ -140,7 +140,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
| 方法 | 描述 | 类型 | 版本限制 |
| --- | --- | --- | --- |
| setState | 动态设置弹窗状态属性 | `(((prev: ModalState) => Partial<ModalState>)\| Partial<ModalState>)=>drawerApi` |
| setState | 动态设置抽屉状态属性 | `(((prev: DrawerState) => Partial<DrawerState>)\| Partial<DrawerState>)=>drawerApi` |
| open | 打开弹窗 | `()=>void` | --- |
| close | 关闭弹窗 | `()=>void` | --- |
| setData | 设置共享数据 | `<T>(data:T)=>drawerApi` | --- |

View File

@@ -4,31 +4,31 @@ outline: deep
# Vben EllipsisText 省略文本
框架提供的文本展示组件,可配置超长省略、tooltip提示展开收起等功能
`EllipsisText` 用于展示超长文本,支持省略、Tooltip 提示以及点击展开收起。
> 如果文档内没有参数说明,可以尝试在在线示例内寻找
> 如果文档内没有覆盖到你需要的细节,可以结合在线示例一起查看。
## 基础用法
通过默认插槽设置文本内容,`maxWidth`属性设置最大宽度。
通过默认插槽提供文本内容,`maxWidth` 用于限制文本区域宽度。
<DemoPreview dir="demos/vben-ellipsis-text/line" />
## 可折叠文本
## 可折叠文本
通过`line`设置折叠后的行数,`expand`属性设置是否支持展开收起。
通过 `line` 设置折叠后的最大行数,通过 `expand` 开启点击展开收起。
<DemoPreview dir="demos/vben-ellipsis-text/expand" />
## 自定义提示浮层
通过名为`tooltip`插槽定制提示信息
通过 `tooltip` 插槽自定义提示内容
<DemoPreview dir="demos/vben-ellipsis-text/tooltip" />
## 自动显示 tooltip
## 仅在省略时显示 Tooltip
通过`tooltip-when-ellipsis`设置,仅在文本长度超出导致省略号出现时才触发 tooltip。
通过 `tooltip-when-ellipsis` 控制仅在文本被截断时显示 Tooltip。
<DemoPreview dir="demos/vben-ellipsis-text/auto-display" />
@@ -38,27 +38,27 @@ outline: deep
| 属性名 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| expand | 支持点击展开或收起 | `boolean` | `false` |
| line | 文本最大行数 | `number` | `1` |
| expand | 是否支持点击展开或收起 | `boolean` | `false` |
| line | 文本最大显示行数 | `number` | `1` |
| maxWidth | 文本区域最大宽度 | `number \| string` | `'100%'` |
| placement | 提示浮层位置 | `'bottom'\|'left'\|'right'\|'top'` | `'top'` |
| tooltip | 启用文本提示 | `boolean` | `true` |
| tooltipWhenEllipsis | 内容超出,自动启用文本提示 | `boolean` | `false` |
| ellipsisThreshold | 设置 tooltipWhenEllipsis 后才生效,文本截断检测的像素差异阈值,越大则判断越严格,如果碰见异常情况可以自己设置阈值 | `number` | `3` |
| tooltipBackgroundColor | 提示文本的背景色 | `string` | - |
| tooltipColor | 提示文本的颜色 | `string` | - |
| tooltipFontSize | 提示文本的大小 | `string` | - |
| tooltipMaxWidth | 提示浮层的最大宽度。如不设置则保持与文本宽度一致 | `number` | - |
| tooltipOverlayStyle | 提示内容区域样式 | `CSSProperties` | `{ textAlign: 'justify' }` |
| placement | 提示浮层位置 | `'bottom' \| 'left' \| 'right' \| 'top'` | `'top'` |
| tooltip | 是否启用文本提示 | `boolean` | `true` |
| tooltipWhenEllipsis | 是否仅在文本被截断时显示提示 | `boolean` | `false` |
| ellipsisThreshold | 文本截断检测阈值,越大判定越严格 | `number` | `3` |
| tooltipBackgroundColor | 提示背景色 | `string` | `''` |
| tooltipColor | 提示文颜色 | `string` | `''` |
| tooltipFontSize | 提示文字大小,单位 `px` | `number` | `14` |
| tooltipMaxWidth | 提示内容最大宽度,单位 `px` | `number` | - |
| tooltipOverlayStyle | 提示内容区域样式 | `CSSProperties` | `{ textAlign: 'justify' }` |
### Events
| 事件名 | 描述 | 类型 |
| ------------ | ------------ | -------------------------- |
| expandChange | 展开状态变 | `(isExpand:boolean)=>void` |
| 事件名 | 描述 | 类型 |
| ------------ | ------------------ | ----------------------------- |
| expandChange | 展开状态变化时触发 | `(isExpand: boolean) => void` |
### Slots
| 插槽名 | 描述 |
| ------- | -------------------------------- |
| tooltip | 启文本提示时,用来定制提示内容 |
| 插槽名 | 描述 |
| ------- | ---------------------------------- |
| tooltip | 启文本提示时,用于自定义提示内容 |

View File

@@ -35,10 +35,15 @@ import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { initComponentAdapter } from './component';
initComponentAdapter();
setupVbenForm<ComponentType>({
config: {
// ant design vue组件库默认都是 v-model:value
baseModelPropName: 'value',
// 一些组件库空值为 null重置表单时需要和实际组件行为保持一致
emptyStateValue: null,
// 一些组件是 v-model:checked 或者 v-model:fileList
modelPropNameMap: {
Checkbox: 'checked',
@@ -87,55 +92,32 @@ import type { BaseFormComponentType } from '@vben/common-ui';
import type { Component, SetupContext } from 'vue';
import { h } from 'vue';
import { globalShareState, IconPicker } from '@vben/common-ui';
import { globalShareState } from '@vben/common-ui';
import { $t } from '@vben/locales';
const AutoComplete = defineAsyncComponent(
() => import('ant-design-vue/es/auto-complete'),
);
const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
const Checkbox = defineAsyncComponent(
() => import('ant-design-vue/es/checkbox'),
);
const CheckboxGroup = defineAsyncComponent(() =>
import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
);
const DatePicker = defineAsyncComponent(
() => import('ant-design-vue/es/date-picker'),
);
const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
const InputNumber = defineAsyncComponent(
() => import('ant-design-vue/es/input-number'),
);
const InputPassword = defineAsyncComponent(() =>
import('ant-design-vue/es/input').then((res) => res.InputPassword),
);
const Mentions = defineAsyncComponent(
() => import('ant-design-vue/es/mentions'),
);
const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
const RadioGroup = defineAsyncComponent(() =>
import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
);
const RangePicker = defineAsyncComponent(() =>
import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
);
const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
const Textarea = defineAsyncComponent(() =>
import('ant-design-vue/es/input').then((res) => res.Textarea),
);
const TimePicker = defineAsyncComponent(
() => import('ant-design-vue/es/time-picker'),
);
const TreeSelect = defineAsyncComponent(
() => import('ant-design-vue/es/tree-select'),
);
const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
import {
AutoComplete,
Button,
Checkbox,
CheckboxGroup,
DatePicker,
Divider,
Input,
InputNumber,
InputPassword,
Mentions,
notification,
Radio,
RadioGroup,
RangePicker,
Rate,
Select,
Space,
Switch,
Textarea,
TimePicker,
TreeSelect,
Upload,
} from 'ant-design-vue';
const withDefaultPlaceholder = <T extends Component>(
component: T,
@@ -171,7 +153,6 @@ export type ComponentType =
| 'TimePicker'
| 'TreeSelect'
| 'Upload'
| 'IconPicker';
| BaseFormComponentType;
async function initComponentAdapter() {
@@ -189,7 +170,6 @@ async function initComponentAdapter() {
return h(Button, { ...props, attrs, type: 'default' }, slots);
},
Divider,
IconPicker,
Input: withDefaultPlaceholder(Input, 'input'),
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),

View File

@@ -69,7 +69,7 @@ Modal 内的内容一般业务中,会比较复杂,所以我们可以将 moda
- `VbenModal` 组件对与参数的处理优先级是 `slot` > `props` > `state`(通过api更新的状态以及useVbenModal参数)。如果你已经传入了 `slot` 或者 `props`,那么 `setState` 将不会生效,这种情况下你可以通过 `slot` 或者 `props` 来更新状态。
- 如果你使用到了 `connectedComponent` 参数,那么会存在 2 个`useVbenModal`, 此时,如果同时设置了相同的参数,那么以内部为准(也就是没有设置 connectedComponent 的代码)。比如 同时设置了 `onConfirm`,那么以内部的 `onConfirm` 为准。`onOpenChange`事件除外,内外都会触发。另外,如果设置了`destroyOnClose`内部Modal及其子组件会在被关闭后<b>完全销毁</b>。
- 如果弹窗的默认行为不符合你的预期,可以在`src\bootstrap.ts`中修改`setDefaultModalProps`的参数来设置默认属性,如默认隐藏全屏按钮修改默认ZIndex等。
- 如果弹窗的默认行为不符合你的预期,可以在对应应用的 `apps/<app>/src/bootstrap.ts` 中修改 `setDefaultModalProps` 的参数来设置默认属性,如默认隐藏全屏按钮修改默认 `zIndex` 等。
:::

View File

@@ -4,25 +4,19 @@ outline: deep
# Vben Vxe Table 表格
框架提供的Table 列表组件基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid),结合`Vben Form 表单`进行了二次封装
`Vben Vxe Table` 基于 [vxe-table](https://vxetable.cn/v4/#/grid/api?apiKey=grid)`Vben Form` 做了二次封装,用于构建带搜索表单的列表页面
其中,表头的 **表单搜索** 部分采用了`Vben Form表单`,表格主体部分使用了`vxe-grid`组件,支持表格的分页、排序、筛选等功能
> 如果文档内没有参数说明,可以尝试在在线示例或者在 [vxe-grid 官方API 文档](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 内寻找
> 如果文档内没有覆盖到你需要的细节,可以结合在线示例和 [vxe-grid 官方 API](https://vxetable.cn/v4/#/grid/api?apiKey=grid) 一起查看
::: info 写在前面
如果你觉得现有组件的封装不够理想,或者不完全符合你的需求,大可以直接使用原生组件,亦或亲手封装一个适合的组件。框架提供的组件并非束缚,使用与否,完全取决于你的需求与自由。
:::
如果现有封装不满足你的场景,可以直接使用原生 `vxe-table` 能力,或者在适配层中继续扩展。:::
## 适配器
表格底层使用 [vxe-table](https://vxetable.cn/#/start/install) 进行实现,所以你可以使用 `vxe-table` 的所有功能。对于不同的 UI 框架,我们提供了适配器,以便更好的适配不同的 UI 框架
底层表格基于 `vxe-table`,每个应用都可以在自己的适配层中配置默认行为、自定义渲染器以及与 UI 组件库的集成
### 适配器说明
每个应用都可以自己配置`vxe-table`的适配器,你可以根据自己的需求。下面是一个简单的配置示例:
### 适配器示例
::: details vxe-table 表格适配器
@@ -46,7 +40,6 @@ setupVbenVxeTable({
},
minHeight: 180,
formConfig: {
// 全局禁用vxe-table的表单配置使用formOptions
enabled: false,
},
proxyConfig: {
@@ -65,7 +58,6 @@ setupVbenVxeTable({
},
});
// 表格配置项可以用 cellRender: { name: 'CellImage' },
vxeUI.renderer.add('CellImage', {
renderTableDefault(_renderOpts, params) {
const { column, row } = params;
@@ -73,7 +65,6 @@ setupVbenVxeTable({
},
});
// 表格配置项可以用 cellRender: { name: 'CellLink' },
vxeUI.renderer.add('CellLink', {
renderTableDefault(renderOpts) {
const { props } = renderOpts;
@@ -84,9 +75,6 @@ setupVbenVxeTable({
);
},
});
// 这里可以自行扩展 vxe-table 的全局配置,比如自定义格式化
// vxeUI.formats.add
},
useVbenForm,
});
@@ -100,55 +88,50 @@ export type * from '@vben/plugins/vxe-table';
## 基础表格
使用 `useVbenVxeGrid` 创建基础表格。
通过 `useVbenVxeGrid` 创建一个基础表格。
<DemoPreview dir="demos/vben-vxe-table/basic" />
## 远程加载
通过指定 `proxyConfig.ajax``query` 方法,可以实现远程加载数据
通过配置 `proxyConfig.ajax.query` 实现远程数据加载
<DemoPreview dir="demos/vben-vxe-table/remote" />
## 树形表格
树形表格的数据源扁平结构,可以指定`treeConfig`配置项,实现树形表格
树形表格的数据源通常是扁平结构,可以通过 `treeConfig` 转换为树形展示
```typescript
```ts
treeConfig: {
transform: true, // 指定表格为树形表格
parentField: 'parentId', // 父节点字段名
rowField: 'id', // 行数据字段名
transform: true,
parentField: 'parentId',
rowField: 'id',
},
```
<DemoPreview dir="demos/vben-vxe-table/tree" />
## 固定表头/
## 固定列
固定可选参数: `'left' | 'right' | '' | null`
固定可选值为 `'left' | 'right' | '' | null`
<DemoPreview dir="demos/vben-vxe-table/fixed" />
## 自定义单元格
自定义单元格有两种实现方式
可以通过插槽或自定义渲染器实现单元格定制。
- 通过 `slots` 插槽
- 通过 `customCell` 自定义单元格,但是要先添加渲染器
```typescript
// 表格配置项可以用 cellRender: { name: 'CellImage' },
```ts
vxeUI.renderer.add('CellImage', {
renderDefault(_renderOpts, params) {
renderTableDefault(_renderOpts, params) {
const { column, row } = params;
return h(Image, { src: row[column.field] } as any); // 注意此处的Image 组件来源于Antd需要自行引入,否则会使用js的Image类
return h(Image, { src: row[column.field] } as any);
},
});
// 表格配置项可以用 cellRender: { name: 'CellLink' },
vxeUI.renderer.add('CellLink', {
renderDefault(renderOpts) {
renderTableDefault(renderOpts) {
const { props } = renderOpts;
return h(
Button,
@@ -163,23 +146,20 @@ vxeUI.renderer.add('CellLink', {
## 搜索表单
**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)
搜索区域底层使用的是 `Vben Form`。启用搜索表单后,可以通过 `gridOptions.toolbarConfig.search = true` 在工具栏中显示搜索面板开关按钮
当启用了表单搜索时可以在toolbarConfig中配置`search``true`来让表格在工具栏区域显示一个搜索表单控制按钮。表格的所有以`form-`开头的名插槽都会被传递给搜索表单。
所有以 `form-` 开头的名插槽都会自动转发到搜索表单。
### 定制分隔条
### 自定义分隔条
当你启用表单搜索时,表单和表格之间会显示一个分隔条。这个分隔条使用了默认的组件背景色并且横向贯穿整个Vben Vxe Table在视觉上融入了页面的默认背景中。如果你在Vben Vxe Table的外层包裹了一个不同背景色的容器如将其放在一个Card内默认的表单和表格之间的分隔条可能就显得格格不入了下面的代码演示了如何定制这个分隔条
启用搜索表单时,表单和表格主体之间默认会显示一个分隔条。可以通过 `separator` 调整或关闭它
```ts
const [Grid] = useVbenVxeGrid({
formOptions: {},
gridOptions: {},
// 完全移除分隔条
separator: false,
// 你也可以使用下面的代码来移除分隔条
// separator: { show: false },
// 或者使用下面的代码来改变分隔条的颜色
// separator: { backgroundColor: 'rgba(100,100,0,0.5)' },
});
```
@@ -188,40 +168,36 @@ const [Grid] = useVbenVxeGrid({
## 单元格编辑
通过指定`editConfig.mode``cell`,可以实现单元格编辑。
通过设置 `editConfig.mode = 'cell'` 开启单元格编辑。
<DemoPreview dir="demos/vben-vxe-table/edit-cell" />
## 行编辑
通过指定`editConfig.mode``row`,可以实现行编辑。
通过设置 `editConfig.mode = 'row'` 开启整行编辑。
<DemoPreview dir="demos/vben-vxe-table/edit-row" />
## 虚拟滚动
通过 scroll-y.enabledscroll-y.gt 组合开启,其中 enabled 为总开关gt 是指当总行数大于指定行数时自动开启
通过 `scroll-y.enabled``scroll-y.gt` 组合开启纵向虚拟滚动
> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)
> 参考 [vxe-table 官方文档 - 虚拟滚动](https://vxetable.cn/v4/#/component/grid/scroll/vertical)
<DemoPreview dir="demos/vben-vxe-table/virtual" />
## API
`useVbenVxeGrid` 返回一个数组,第一个元素是表格组件,第二个元素是表格的方法
`useVbenVxeGrid` 返回一个数组,第一个元素是表格组件,第二个元素是表格 API
```vue
<script setup lang="ts">
import { useVbenVxeGrid } from '#/adapter/vxe-table';
// Grid 为表格组件
// gridApi 为表格的方法
const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: {},
formOptions: {},
gridEvents: {},
// 属性
// 事件
});
</script>
@@ -232,45 +208,42 @@ const [Grid, gridApi] = useVbenVxeGrid({
### GridApi
useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表单的方法。
| 方法名 | 描述 | 类型 | 说明 |
| --- | --- | --- | --- |
| setLoading | 设置loading状态 | `(loading)=>void` | - |
| setGridOptions | 设置vxe-table grid组件参数 | `(options: Partial<VxeGridProps['gridOptions'])=>void` | - |
| reload | 重载表格,会进行初始化 | `(params:any)=>void` | - |
| query | 重表格,保留当前分页 | `(params:any)=>void` | - |
| grid | vxe-table grid实例 | `VxeGridInstance` | - |
| formApi | vbenForm api实例 | `FormApi` | - |
| toggleSearchForm | 设置搜索表单显示状态 | `(show?: boolean)=>boolean` | 当省略参数时,则将表单在显示和隐藏两种状态之间切换 |
| setLoading | 设置 loading 状态 | `(loading: boolean) => void` | - |
| setGridOptions | 更新 `gridOptions` | `(options: Partial<VxeGridProps['gridOptions']>) => void` | - |
| reload | 重新加载表格,并重置到初始分页 | `(params?: Record<string, any>) => void` | - |
| query | 重新查询表格,保留当前分页 | `(params?: Record<string, any>) => void` | - |
| grid | `vxe-grid` 实例 | `VxeGridInstance` | - |
| formApi | 搜索表单 API 实例 | `FormApi` | - |
| toggleSearchForm | 切换或指定搜索表单显示状态 | `(show?: boolean) => boolean` | 传入参数时强制设置;不传参数时在显示和隐藏之间切换,并返回当前状态 |
## Props
所有属性都可以传入 `useVbenVxeGrid` 的第一个参数
所有属性都通过 `useVbenVxeGrid` 的第一个参数传入
| 属性名 | 描述 | 类型 | 版本要求 |
| --- | --- | --- | --- |
| tableTitle | 表格标题 | `string` | - |
| tableTitleHelp | 表格标题帮助信息 | `string` | - |
| gridClass | grid组件的class | `string` | - |
| gridOptions | grid组件的参数 | `VxeTableGridProps` | - |
| gridEvents | grid组件的触发的事件 | `VxeGridListeners` | - |
| formOptions | 表单参数 | `VbenFormProps` | - |
| class | 外层容器的 class | `string` | - |
| gridClass | `vxe-grid` 的 class | `string` | - |
| gridOptions | `vxe-grid` 配置 | `DeepPartial<VxeTableGridOptions>` | - |
| gridEvents | `vxe-grid` 事件 | `DeepPartial<VxeGridListeners>` | - |
| formOptions | 搜索表单配置 | `VbenFormProps` | - |
| showSearchForm | 是否显示搜索表单 | `boolean` | - |
| separator | 搜索表单与表格主体之间的分隔条 | `boolean\|SeparatorOptions` | >5.5.4 |
| separator | 搜索表单与表格主体之间的分隔条 | `boolean \| SeparatorOptions` | `>5.5.4` |
## Slots
大部分插槽说明参考 [vxe-table 官方文档](https://vxetable.cn/v4/#/grid/api)但工具栏部分由于做了一些定制封装,需使用以下插槽定制表格的工具栏:
大部分插槽说明参考 [vxe-table 官方文档](https://vxetable.cn/v4/#/grid/api)这里列出封装层新增或约定的部分。
| 插槽名 | 描述 |
| --------------- | -------------------------------------------- |
| toolbar-actions | 工具栏左侧部分(表格标题附近) |
| toolbar-tools | 工具栏右侧部分vxeTable原生工具按钮左侧 |
| table-title | 表格标题插槽 |
| 插槽名 | 描述 |
| --------------- | ------------------------------------ |
| toolbar-actions | 工具栏左侧区域,位于标题附近 |
| toolbar-tools | 工具栏右侧区域,位于内置工具按钮左侧 |
| table-title | 自定义表格标题 |
::: info 搜索表单插槽
::: info 搜索表单插槽
对于使用了搜索表单的表格来说,所有以`form-`开头的名插槽都会传递给表单。
:::
当启用了搜索表单,所有以 `form-` 开头的名插槽都会被转发给表单。:::

View File

@@ -4,41 +4,38 @@ outline: deep
# Page 常规页面组件
提供一个常规页面布局的组件,包括头部、内容区域、底部三个部分
`Page` 是页面内容区最常用的顶层布局容器,内置了标题区、内容区和底部区三部分结构
::: info 写在前面
本组件是一个基本布局组件。如果有更多的通用页面布局需求(比如双列布局等),可以根据实际需求自行封装。
:::
是一个基础页面容器。如果你的业务页面需要更复杂的布局,例如双列、侧边操作区或自定义滚动区域,建议在 `Page` 之上继续封装。:::
## 基础用法
`Page`作为你的业务页面的根组件即可。
直接将 `Page` 作为业务页面的根组件使用即可。
### Props
| 属性名 | 描述 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- | --- |
| title | 页面标题 | `string\|slot` | - | - |
| description | 页面描述(标题下的内容) | `string\|slot` | - | - |
| contentClass | 内容区域的class | `string` | - | - |
| headerClass | 头部区域的class | `string` | - | - |
| footerClass | 底部区域的class | `string` | - | - |
| autoContentHeight | 自动调整内容区域的高度 | `boolean` | `false` | - |
| title | 页面标题 | `string \| slot` | - | - |
| description | 页面描述 | `string \| slot` | - | - |
| contentClass | 内容区域的 class | `string` | - | - |
| headerClass | 头部区域的 class | `string` | - | - |
| footerClass | 底部区域的 class | `string` | - | - |
| autoContentHeight | 根据可视内容高度自动计算内容区高度 | `boolean` | `false` | 开启后内容区会根据布局可视高度自动扣减头部和底部高度 |
| heightOffset | 额外扣减的内容区高度偏移量 | `number` | `0` | 仅在 `autoContentHeight` 开启时生效,单位为 `px` |
::: tip 注意
如果`title``description``extra`三者均未提供有效内容通过`props`或者`slots`均可),则页面头部区域不会渲染。
:::
如果 `title``description``extra` 三者都没有提供有效内容,无论是通过 `props` 还是 `slots`头部区域不会渲染。:::
### Slots
| 插槽名称 | 描述 |
| ----------- | ------------ |
| default | 页面内容 |
| title | 页面标题 |
| description | 页面描述 |
| extra | 页面头部右侧 |
| footer | 页面底部 |
| 插槽名称 | 描述 |
| ----------- | ---------------- |
| default | 页面内容 |
| title | 页面标题 |
| description | 页面描述 |
| extra | 页面头部右侧内容 |
| footer | 页面底部内容 |

View File

@@ -0,0 +1,76 @@
---
outline: deep
---
# Vben Alert
`Alert` provides lightweight JavaScript-driven dialogs for simple `alert`, `confirm`, and `prompt` style interactions.
## Basic Usage
Use `alert` for a single confirm button dialog:
<DemoPreview dir="demos/vben-alert/alert" />
Use `confirm` for confirm/cancel interactions:
<DemoPreview dir="demos/vben-alert/confirm" />
Use `prompt` when you need simple user input:
<DemoPreview dir="demos/vben-alert/prompt" />
## useAlertContext
If `content`, `footer`, or `icon` is rendered through a custom component, you can call `useAlertContext()` inside that component to access the current dialog actions.
| Method | Description | Type |
| ----------- | -------------------------- | ------------ |
| `doConfirm` | trigger the confirm action | `() => void` |
| `doCancel` | trigger the cancel action | `() => void` |
## Core Types
```ts
export type IconType = 'error' | 'info' | 'question' | 'success' | 'warning';
export type BeforeCloseScope = {
isConfirm: boolean;
};
export type AlertProps = {
beforeClose?: (
scope: BeforeCloseScope,
) => boolean | Promise<boolean | undefined> | undefined;
bordered?: boolean;
buttonAlign?: 'center' | 'end' | 'start';
cancelText?: string;
centered?: boolean;
confirmText?: string;
containerClass?: string;
content: Component | string;
contentClass?: string;
contentMasking?: boolean;
footer?: Component | string;
icon?: Component | IconType;
overlayBlur?: number;
showCancel?: boolean;
title?: string;
};
export type PromptProps<T = any> = {
beforeClose?: (scope: {
isConfirm: boolean;
value: T | undefined;
}) => boolean | Promise<boolean | undefined> | undefined;
component?: Component;
componentProps?: Recordable<any>;
componentSlots?:
| (() => any)
| Recordable<unknown>
| VNode
| VNodeArrayChildren;
defaultValue?: T;
modelPropName?: string;
} & Omit<AlertProps, 'beforeClose'>;
```

View File

@@ -0,0 +1,69 @@
---
outline: deep
---
# Vben ApiComponent
`ApiComponent` is a wrapper used to attach remote-option loading behavior to an existing component while preserving the original component usage pattern.
## Common Usage
The current wrapper flow is:
- pass the target component through `component`
- fetch remote data through `api`
- transform data through `beforeFetch` and `afterFetch`
- map remote fields through `resultField`, `valueField`, `labelField`, and `childrenField`
- pass normalized options to the target component through `optionsPropName`
```vue
<script lang="ts" setup>
import { ApiComponent } from '@vben/common-ui';
import { Cascader } from 'ant-design-vue';
function fetchApi() {
return Promise.resolve([
{
label: 'Zhejiang',
value: 'zhejiang',
children: [{ label: 'Hangzhou', value: 'hangzhou' }],
},
]);
}
</script>
<template>
<ApiComponent
:api="fetchApi"
:component="Cascader"
:immediate="false"
children-field="children"
loading-slot="suffixIcon"
visible-event="onDropdownVisibleChange"
/>
</template>
```
## Current Props
| Prop | Description | Type |
| --- | --- | --- |
| `component` | wrapped target component | `Component` |
| `api` | remote request function | `(arg?: any) => Promise<any>` |
| `params` | extra request params | `Record<string, any>` |
| `beforeFetch` | hook before request | `AnyPromiseFunction` |
| `afterFetch` | hook after request | `AnyPromiseFunction` |
| `visibleEvent` | event name used to lazy-load data | `string` |
| `loadingSlot` | slot name used to render the loading icon | `string` |
| `modelPropName` | model prop name of the wrapped component | `string` |
| `autoSelect` | auto-pick the first / last / only option, or use a custom function | `'first' \| 'last' \| 'one' \| ((items) => item) \| false` |
## Exposed Methods
| Method | Description |
| ------------------------ | -------------------------------------- |
| `getComponentRef()` | returns the wrapped component instance |
| `updateParam(newParams)` | merges and updates request params |
| `getOptions()` | returns loaded options |
| `getValue()` | returns the current bound value |

View File

@@ -0,0 +1,51 @@
---
outline: deep
---
# Vben CountToAnimator
`CountToAnimator` renders animated number transitions.
## Basic Usage
Use `start-val`, `end-val`, and `duration` to control the animation range and timing.
<DemoPreview dir="demos/vben-count-to-animator/basic" />
## Formatting
Use `prefix`, `suffix`, `separator`, and `decimal` to control how the number is displayed.
<DemoPreview dir="demos/vben-count-to-animator/custom" />
## Props
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| `startVal` | starting value | `number` | `0` |
| `endVal` | ending value | `number` | `2021` |
| `duration` | animation duration in ms | `number` | `1500` |
| `autoplay` | start automatically | `boolean` | `true` |
| `prefix` | value prefix | `string` | `''` |
| `suffix` | value suffix | `string` | `''` |
| `separator` | thousands separator | `string` | `','` |
| `decimal` | decimal separator | `string` | `'.'` |
| `color` | text color | `string` | `''` |
| `useEasing` | enable transition preset easing | `boolean` | `true` |
| `transition` | transition preset name | `keyof typeof TransitionPresets` | `'linear'` |
| `decimals` | decimal places to keep | `number` | `0` |
## Events
| Event | Description | Type |
| ------------ | ------------------------------- | ------------ |
| `started` | fired when the animation starts | `() => void` |
| `finished` | fired when the animation ends | `() => void` |
| `onStarted` | deprecated alias of `started` | `() => void` |
| `onFinished` | deprecated alias of `finished` | `() => void` |
## Exposed Methods
| Method | Description | Type |
| ------- | --------------------------------- | ------------ |
| `reset` | reset to `startVal` and run again | `() => void` |

View File

@@ -0,0 +1,56 @@
---
outline: deep
---
# Vben Drawer
`Vben Drawer` is the shared drawer wrapper used by the framework. It supports auto-height layout, loading state, connected components, and an imperative API similar to the modal API.
## Basic Usage
```ts
const [Drawer, drawerApi] = useVbenDrawer({
// props
// events
});
```
<DemoPreview dir="demos/vben-drawer/basic" />
## Current Usage Notes
- If you use `connectedComponent`, the inner and outer components share data through `drawerApi.setData()` and `drawerApi.getData()`.
- Default drawer behavior can be adjusted in `apps/<app>/src/bootstrap.ts` through `setDefaultDrawerProps(...)`.
- `setState(...)` works on `DrawerState`, not `ModalState`.
## Key Props
| Prop | Description | Type |
| --- | --- | --- |
| `appendToMain` | mount inside the main content area instead of `body` | `boolean` |
| `connectedComponent` | connect an inner component to the drawer wrapper | `Component` |
| `closeIconPlacement` | position of the close icon | `'left' \| 'right'` |
| `placement` | drawer side | `'left' \| 'right' \| 'top' \| 'bottom'` |
| `overlayBlur` | blur amount for the overlay | `number` |
| `submitting` | lock drawer interactions while submitting | `boolean` |
## Events
| Event | Description | Type |
| --- | --- | --- |
| `onBeforeClose` | called before close; returning `false` or rejecting prevents close | `() => Promise<boolean \| undefined> \| boolean \| undefined` |
| `onOpenChange` | called when open state changes | `(isOpen: boolean) => void` |
| `onOpened` | called after open animation completes | `() => void` |
| `onClosed` | called after close animation completes | `() => void` |
## drawerApi
| Method | Description |
| ----------------------- | -------------------------------------- |
| `setState(...)` | updates drawer state |
| `open()` | opens the drawer |
| `close()` | closes the drawer |
| `setData(data)` | stores shared data |
| `getData<T>()` | reads shared data |
| `lock(isLocked = true)` | locks the drawer into submitting state |
| `unlock()` | alias for `lock(false)` |

View File

@@ -0,0 +1,42 @@
---
outline: deep
---
# Vben EllipsisText
`EllipsisText` displays long text with truncation, tooltip support, and optional expand/collapse behavior.
## Basic Usage
Pass the text through the default slot and limit the visual width with `maxWidth`.
<DemoPreview dir="demos/vben-ellipsis-text/line" />
## Current Props
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| `expand` | allow click-to-expand behavior | `boolean` | `false` |
| `line` | max visible line count | `number` | `1` |
| `maxWidth` | max width of the text area | `number \| string` | `'100%'` |
| `placement` | tooltip placement | `'bottom' \| 'left' \| 'right' \| 'top'` | `'top'` |
| `tooltip` | enable tooltip | `boolean` | `true` |
| `tooltipWhenEllipsis` | only show tooltip when text is actually truncated | `boolean` | `false` |
| `ellipsisThreshold` | pixel threshold used when checking truncation | `number` | `3` |
| `tooltipBackgroundColor` | tooltip background color | `string` | `''` |
| `tooltipColor` | tooltip text color | `string` | `''` |
| `tooltipFontSize` | tooltip font size in px | `number` | `14` |
| `tooltipMaxWidth` | tooltip max width in px | `number` | - |
| `tooltipOverlayStyle` | tooltip content style | `CSSProperties` | `{ textAlign: 'justify' }` |
## Events
| Event | Description | Type |
| --- | --- | --- |
| `expandChange` | fired when expand state changes | `(isExpand: boolean) => void` |
## Slots
| Slot | Description |
| --------- | ---------------------- |
| `tooltip` | custom tooltip content |

View File

@@ -0,0 +1,203 @@
---
outline: deep
---
# Vben Form
`Vben Form` is the shared form abstraction used across different UI-library variants such as `Ant Design Vue`, `Element Plus`, `Naive UI`, and other adapters added inside this repository.
> If some details are not obvious from the docs, check the live demos as well.
## Adapter Setup
Each app keeps its own adapter layer under `src/adapter/form.ts` and `src/adapter/component/index.ts`.
The current adapter pattern is:
- initialize the shared component adapter first
- call `setupVbenForm(...)`
- map special `v-model:*` prop names through `modelPropNameMap`
- keep the form empty state aligned with the actual UI library behavior
### Form Adapter Example
```ts
import type {
VbenFormSchema as FormSchema,
VbenFormProps,
} from '@vben/common-ui';
import type { ComponentType } from './component';
import { setupVbenForm, useVbenForm as useForm, z } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { initComponentAdapter } from './component';
initComponentAdapter();
setupVbenForm<ComponentType>({
config: {
baseModelPropName: 'value',
emptyStateValue: null,
modelPropNameMap: {
Checkbox: 'checked',
Radio: 'checked',
Switch: 'checked',
Upload: 'fileList',
},
},
defineRules: {
required: (value, _params, ctx) => {
if (value === undefined || value === null || value.length === 0) {
return $t('ui.formRules.required', [ctx.label]);
}
return true;
},
selectRequired: (value, _params, ctx) => {
if (value === undefined || value === null) {
return $t('ui.formRules.selectRequired', [ctx.label]);
}
return true;
},
},
});
const useVbenForm = useForm<ComponentType>;
export { useVbenForm, z };
export type VbenFormSchema = FormSchema<ComponentType>;
export type { VbenFormProps };
```
### Component Adapter Example
```ts
import type { Component, SetupContext } from 'vue';
import type { BaseFormComponentType } from '@vben/common-ui';
import { h } from 'vue';
import { globalShareState } from '@vben/common-ui';
import { $t } from '@vben/locales';
import {
AutoComplete,
Button,
Checkbox,
CheckboxGroup,
DatePicker,
Divider,
Input,
InputNumber,
InputPassword,
Mentions,
notification,
Radio,
RadioGroup,
RangePicker,
Rate,
Select,
Space,
Switch,
Textarea,
TimePicker,
TreeSelect,
Upload,
} from 'ant-design-vue';
const withDefaultPlaceholder = <T extends Component>(
component: T,
type: 'input' | 'select',
) => {
return (props: any, { attrs, slots }: Omit<SetupContext, 'expose'>) => {
const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`);
return h(component, { ...props, ...attrs, placeholder }, slots);
};
};
export type ComponentType =
| 'AutoComplete'
| 'Checkbox'
| 'CheckboxGroup'
| 'DatePicker'
| 'DefaultButton'
| 'Divider'
| 'Input'
| 'InputNumber'
| 'InputPassword'
| 'Mentions'
| 'PrimaryButton'
| 'Radio'
| 'RadioGroup'
| 'RangePicker'
| 'Rate'
| 'Select'
| 'Space'
| 'Switch'
| 'Textarea'
| 'TimePicker'
| 'TreeSelect'
| 'Upload'
| BaseFormComponentType;
async function initComponentAdapter() {
const components: Partial<Record<ComponentType, Component>> = {
AutoComplete,
Checkbox,
CheckboxGroup,
DatePicker,
DefaultButton: (props, { attrs, slots }) => {
return h(Button, { ...props, attrs, type: 'default' }, slots);
},
Divider,
Input: withDefaultPlaceholder(Input, 'input'),
InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
Mentions: withDefaultPlaceholder(Mentions, 'input'),
PrimaryButton: (props, { attrs, slots }) => {
return h(Button, { ...props, attrs, type: 'primary' }, slots);
},
Radio,
RadioGroup,
RangePicker,
Rate,
Select: withDefaultPlaceholder(Select, 'select'),
Space,
Switch,
Textarea: withDefaultPlaceholder(Textarea, 'input'),
TimePicker,
TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
Upload,
};
globalShareState.setComponents(components);
globalShareState.defineMessage({
copyPreferencesSuccess: (title, content) => {
notification.success({
description: content,
message: title,
placement: 'bottomRight',
});
},
});
}
export { initComponentAdapter };
```
## Basic Usage
Create the form through `useVbenForm`:
<DemoPreview dir="demos/vben-form/basic" />
## Key API Notes
- `useVbenForm` returns `[Form, formApi]`
- `formApi.getFieldComponentRef()` and `formApi.getFocusedField()` are available in current versions
- `handleValuesChange(values, fieldsChanged)` includes the second parameter in newer versions
- `fieldMappingTime` and `scrollToFirstError` are part of the current form props
## Reference
For the complete Chinese API tables and more examples, see the Chinese component page if you need the full parameter matrix.

View File

@@ -0,0 +1,56 @@
---
outline: deep
---
# Vben Modal
`Vben Modal` is the shared modal wrapper used by the framework. It supports draggable behavior, fullscreen mode, auto-height handling, loading state, connected components, and an imperative API.
## Basic Usage
```ts
const [Modal, modalApi] = useVbenModal({
// props
// events
});
```
<DemoPreview dir="demos/vben-modal/basic" />
## Current Usage Notes
- If you use `connectedComponent`, the inner and outer components share data through `modalApi.setData()` and `modalApi.getData()`.
- When `connectedComponent` is present, avoid pushing extra modal props through the connected side. Prefer `useVbenModal(...)` or `modalApi.setState(...)`.
- Default modal behavior can be adjusted in `apps/<app>/src/bootstrap.ts` through `setDefaultModalProps(...)`.
## Key Props
| Prop | Description | Type |
| --- | --- | --- |
| `appendToMain` | mount inside the main content area instead of `body` | `boolean` |
| `connectedComponent` | connect an inner component to the modal wrapper | `Component` |
| `animationType` | modal enter/leave animation | `'slide' \| 'scale'` |
| `fullscreenButton` | show or hide the fullscreen toggle | `boolean` |
| `overlayBlur` | blur amount for the overlay | `number` |
| `submitting` | lock modal interactions while submitting | `boolean` |
## Events
| Event | Description | Type |
| --- | --- | --- |
| `onBeforeClose` | called before close; returning `false` or rejecting prevents close | `() => Promise<boolean \| undefined> \| boolean \| undefined` |
| `onOpenChange` | called when open state changes | `(isOpen: boolean) => void` |
| `onOpened` | called after open animation completes | `() => void` |
| `onClosed` | called after close animation completes | `() => void` |
## modalApi
| Method | Description |
| ----------------------- | ------------------------------------- |
| `setState(...)` | updates modal state |
| `open()` | opens the modal |
| `close()` | closes the modal |
| `setData(data)` | stores shared data |
| `getData<T>()` | reads shared data |
| `lock(isLocked = true)` | locks the modal into submitting state |
| `unlock()` | alias for `lock(false)` |

View File

@@ -0,0 +1,87 @@
---
outline: deep
---
# Vben Vxe Table
`Vben Vxe Table` wraps `vxe-table` together with `Vben Form` so you can build searchable data grids with a shared API.
## Adapter Example
The current renderer adapter uses `renderTableDefault(...)` for table cell rendering:
```ts
vxeUI.renderer.add('CellImage', {
renderTableDefault(_renderOpts, params) {
const { column, row } = params;
return h(Image, { src: row[column.field] });
},
});
vxeUI.renderer.add('CellLink', {
renderTableDefault(renderOpts) {
const { props } = renderOpts;
return h(
Button,
{ size: 'small', type: 'link' },
{ default: () => props?.text },
);
},
});
```
## Basic Usage
```vue
<script setup lang="ts">
import { useVbenVxeGrid } from '#/adapter/vxe-table';
const [Grid, gridApi] = useVbenVxeGrid({
gridOptions: {},
formOptions: {},
gridEvents: {},
});
</script>
<template>
<Grid />
</template>
```
<DemoPreview dir="demos/vben-vxe-table/basic" />
## GridApi
| Method | Description | Type |
| --- | --- | --- |
| `setLoading` | update loading state | `(loading: boolean) => void` |
| `setGridOptions` | merge new grid options | `(options: Partial<VxeGridProps['gridOptions']>) => void` |
| `reload` | reload data and reset pagination | `(params?: Record<string, any>) => void` |
| `query` | query data while keeping the current page | `(params?: Record<string, any>) => void` |
| `grid` | `vxe-grid` instance | `VxeGridInstance` |
| `formApi` | search form API | `FormApi` |
| `toggleSearchForm` | toggle or force the search form visible state | `(show?: boolean) => boolean` |
## Props
| Prop | Description | Type |
| --- | --- | --- |
| `tableTitle` | table title | `string` |
| `tableTitleHelp` | help text for the table title | `string` |
| `class` | class for the outer container | `string` |
| `gridClass` | class for the `vxe-grid` node | `string` |
| `gridOptions` | `vxe-grid` options | `DeepPartial<VxeTableGridOptions>` |
| `gridEvents` | `vxe-grid` event handlers | `DeepPartial<VxeGridListeners>` |
| `formOptions` | search form options | `VbenFormProps` |
| `showSearchForm` | whether the search form is visible | `boolean` |
| `separator` | separator between the search form and table body | `boolean \| SeparatorOptions` |
## Slots
| Slot | Description |
| ----------------- | ------------------------------------------------------- |
| `toolbar-actions` | left side of the toolbar, near the title |
| `toolbar-tools` | right side of the toolbar, before built-in tool buttons |
| `table-title` | custom table title |
All named slots starting with `form-` are forwarded to the search form.

View File

@@ -0,0 +1,15 @@
# Introduction
::: info README
This section documents the framework components, including their usage patterns, configuration points, and major APIs. If the built-in wrappers do not fit your needs, you can always use native components directly or build your own abstractions.
:::
## Layout Components
Layout components are usually used as top-level containers inside the page content area. They provide shared layout styles and some baseline behavior.
## Common Components
Common components include frequently used UI building blocks such as modals, drawers, forms, and API-backed selectors. Most of them are implemented on top of shared Tailwind CSS and shadcn-vue based primitives, while still allowing each app to adapt them to its own UI library.

View File

@@ -0,0 +1,29 @@
---
outline: deep
---
# Page
`Page` is the standard top-level layout container for business pages. It provides a header area, a content area, and an optional footer area.
## Props
| Prop | Description | Type | Default |
| --- | --- | --- | --- |
| `title` | page title | `string \| slot` | - |
| `description` | page description | `string \| slot` | - |
| `contentClass` | class for the content area | `string` | - |
| `headerClass` | class for the header area | `string` | - |
| `footerClass` | class for the footer area | `string` | - |
| `autoContentHeight` | auto-calculate the content area height from the visible layout height | `boolean` | `false` |
| `heightOffset` | extra height offset subtracted from the content area when auto height is enabled | `number` | `0` |
## Slots
| Slot | Description |
| ------------- | ------------------------- |
| `default` | page content |
| `title` | custom title |
| `description` | custom description |
| `extra` | right-side header content |
| `footer` | footer content |