feat: table search form visible control (#5121)

* feat: table search form visible control

* chore: fix docs and demo

* chore: type error fixed
dev-v5
Netfan 2024-12-12 22:28:03 +08:00 committed by GitHub
parent d308da6ba1
commit ed465d2b5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 112 additions and 26 deletions

View File

@ -165,6 +165,8 @@ vxeUI.renderer.add('CellLink', {
**表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)。 **表单搜索** 部分采用了`Vben Form 表单`,参考 [Vben Form 表单文档](/components/common-ui/vben-form)。
当启用了表单搜索时可以在toolbarConfig中配置`search`为`true`来让表格在工具栏区域显示一个搜索表单控制按钮。
<DemoPreview dir="demos/vben-vxe-table/form" /> <DemoPreview dir="demos/vben-vxe-table/form" />
## 单元格编辑 ## 单元格编辑
@ -215,14 +217,15 @@ const [Grid, gridApi] = useVbenVxeGrid({
useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表单的方法。 useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表单的方法。
| 方法名 | 描述 | 类型 | | 方法名 | 描述 | 类型 | 说明 |
| --- | --- | --- | | --- | --- | --- | --- |
| setLoading | 设置loading状态 | `(loading)=>void` | | setLoading | 设置loading状态 | `(loading)=>void` | - |
| setGridOptions | 设置vxe-table grid组件参数 | `(options: Partial<VxeGridProps['gridOptions'])=>void` | | setGridOptions | 设置vxe-table grid组件参数 | `(options: Partial<VxeGridProps['gridOptions'])=>void` | - |
| reload | 重载表格,会进行初始化 | `(params:any)=>void` | | reload | 重载表格,会进行初始化 | `(params:any)=>void` | - |
| query | 重载表格,会保留当前分页 | `(params:any)=>void` | | query | 重载表格,会保留当前分页 | `(params:any)=>void` | - |
| grid | vxe-table grid实例 | `VxeGridInstance` | | grid | vxe-table grid实例 | `VxeGridInstance` | - |
| formApi | vbenForm api实例 | `FormApi` | | formApi | vbenForm api实例 | `FormApi` | - |
| toggleSearchForm | 设置搜索表单显示状态 | `(show?: boolean)=>boolean` | 当省略参数时,则将表单在显示和隐藏两种状态之间切换 |
## Props ## Props
@ -236,3 +239,4 @@ useVbenVxeGrid 返回的第二个参数,是一个对象,包含了一些表
| gridOptions | grid组件的参数 | `VxeTableGridProps` | | gridOptions | grid组件的参数 | `VxeTableGridProps` |
| gridEvents | grid组件的触发的⌚ | `VxeGridListeners` | | gridEvents | grid组件的触发的⌚ | `VxeGridListeners` |
| formOptions | 表单参数 | `VbenFormProps` | | formOptions | 表单参数 | `VbenFormProps` |
| showSearchForm | 是否显示搜索表单 | `boolean` |

View File

@ -110,6 +110,11 @@ const gridOptions: VxeGridProps<RowType> = {
}, },
}, },
}, },
toolbarConfig: {
//
// @ts-ignore
search: true,
},
}; };
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions }); const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });

View File

@ -8,6 +8,7 @@ import { toRaw } from 'vue';
import { Store } from '@vben-core/shared/store'; import { Store } from '@vben-core/shared/store';
import { import {
bindMethods, bindMethods,
isBoolean,
isFunction, isFunction,
mergeWithArrayOverride, mergeWithArrayOverride,
StateHandler, StateHandler,
@ -20,6 +21,7 @@ function getDefaultState(): VxeGridProps {
gridOptions: {}, gridOptions: {},
gridEvents: {}, gridEvents: {},
formOptions: undefined, formOptions: undefined,
showSearchForm: true,
}; };
} }
@ -108,6 +110,16 @@ export class VxeGridApi {
} }
} }
toggleSearchForm(show?: boolean) {
this.setState({
showSearchForm: isBoolean(show) ? show : !this.state?.showSearchForm,
});
// nextTick(() => {
// this.grid.recalculate();
// });
return this.state?.showSearchForm;
}
unmount() { unmount() {
this.isMounted = false; this.isMounted = false;
this.stateHandler.reset(); this.stateHandler.reset();

View File

@ -1,5 +1,6 @@
export { setupVbenVxeTable } from './init'; export { setupVbenVxeTable } from './init';
export type { VxeTableGridOptions } from './types';
export * from './use-vxe-grid'; export * from './use-vxe-grid';
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
export type { VxeGridListeners, VxeGridProps } from 'vxe-table'; export type { VxeGridListeners, VxeGridProps } from 'vxe-table';

View File

@ -2,6 +2,7 @@ import type { ClassType, DeepPartial } from '@vben/types';
import type { VbenFormProps } from '@vben-core/form-ui'; import type { VbenFormProps } from '@vben-core/form-ui';
import type { import type {
VxeGridListeners, VxeGridListeners,
VxeGridPropTypes,
VxeGridProps as VxeTableGridProps, VxeGridProps as VxeTableGridProps,
VxeUIExport, VxeUIExport,
} from 'vxe-table'; } from 'vxe-table';
@ -18,6 +19,16 @@ export interface VxePaginationInfo {
total: number; total: number;
} }
interface ToolbarConfigOptions extends VxeGridPropTypes.ToolbarConfig {
/** 是否显示切换搜索表单的按钮 */
search?: boolean;
}
export interface VxeTableGridOptions<T = any> extends VxeTableGridProps<T> {
/** 工具栏配置 */
toolbarConfig?: ToolbarConfigOptions;
}
export interface VxeGridProps { export interface VxeGridProps {
/** /**
* *
@ -38,7 +49,7 @@ export interface VxeGridProps {
/** /**
* vxe-grid * vxe-grid
*/ */
gridOptions?: DeepPartial<VxeTableGridProps>; gridOptions?: DeepPartial<VxeTableGridOptions>;
/** /**
* vxe-grid * vxe-grid
*/ */
@ -47,6 +58,10 @@ export interface VxeGridProps {
* *
*/ */
formOptions?: VbenFormProps; formOptions?: VbenFormProps;
/**
*
*/
showSearchForm?: boolean;
} }
export type ExtendedVxeGridApi = { export type ExtendedVxeGridApi = {

View File

@ -1,7 +1,10 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VbenFormProps } from '@vben-core/form-ui'; import type { VbenFormProps } from '@vben-core/form-ui';
import type { import type {
VxeGridDefines,
VxeGridInstance, VxeGridInstance,
VxeGridListeners,
VxeGridPropTypes,
VxeGridProps as VxeTableGridProps, VxeGridProps as VxeTableGridProps,
} from 'vxe-table'; } from 'vxe-table';
@ -57,6 +60,7 @@ const {
formOptions, formOptions,
tableTitle, tableTitle,
tableTitleHelp, tableTitleHelp,
showSearchForm,
} = usePriorityValues(props, state); } = usePriorityValues(props, state);
const { isMobile } = usePreferences(); const { isMobile } = usePreferences();
@ -103,21 +107,37 @@ const toolbarOptions = computed(() => {
const slotActions = slots[TOOLBAR_ACTIONS]?.(); const slotActions = slots[TOOLBAR_ACTIONS]?.();
const slotTools = slots[TOOLBAR_TOOLS]?.(); const slotTools = slots[TOOLBAR_TOOLS]?.();
const toolbarConfig: VxeGridPropTypes.ToolbarConfig = {
tools:
gridOptions.value?.toolbarConfig?.search && !!formOptions.value
? [
{
code: 'search',
icon: 'vxe-icon--search',
circle: true,
status: showSearchForm.value ? 'primary' : undefined,
title: $t('common.search'),
},
]
: [],
};
if (!showToolbar.value) { if (!showToolbar.value) {
return {}; return { toolbarConfig };
} }
// if (gridOptions.value?.toolbarConfig?.search) {
// }
// 使toolbar // 使toolbar
// //
return { toolbarConfig.slots = {
toolbarConfig: { ...(slotActions || showTableTitle.value
slots: { ? { buttons: TOOLBAR_ACTIONS }
...(slotActions || showTableTitle.value : {}),
? { buttons: TOOLBAR_ACTIONS } ...(slotTools ? { tools: TOOLBAR_TOOLS } : {}),
: {}),
...(slotTools ? { tools: TOOLBAR_TOOLS } : {}),
},
},
}; };
return { toolbarConfig };
}); });
const options = computed(() => { const options = computed(() => {
@ -173,9 +193,19 @@ const options = computed(() => {
return mergedOptions; return mergedOptions;
}); });
function onToolbarToolClick(event: VxeGridDefines.ToolbarToolClickEventParams) {
if (event.code === 'search') {
props.api?.toggleSearchForm?.();
}
(
gridEvents.value?.toolbarToolClick as VxeGridListeners['toolbarToolClick']
)?.(event);
}
const events = computed(() => { const events = computed(() => {
return { return {
...gridEvents.value, ...gridEvents.value,
toolbarToolClick: onToolbarToolClick,
}; };
}); });
@ -304,7 +334,11 @@ onUnmounted(() => {
<!-- form表单 --> <!-- form表单 -->
<template #form> <template #form>
<div v-if="formOptions" class="relative rounded py-3 pb-4"> <div
v-if="formOptions"
v-show="showSearchForm !== false"
class="relative rounded py-3 pb-4"
>
<slot name="form"> <slot name="form">
<Form> <Form>
<template <template

View File

@ -9,5 +9,6 @@
"noData": "No Data", "noData": "No Data",
"refresh": "Refresh", "refresh": "Refresh",
"loadingMenu": "Loading Menu", "loadingMenu": "Loading Menu",
"query": "Search" "query": "Search",
"search": "Search"
} }

View File

@ -9,5 +9,6 @@
"noData": "暂无数据", "noData": "暂无数据",
"refresh": "刷新", "refresh": "刷新",
"loadingMenu": "加载菜单中", "loadingMenu": "加载菜单中",
"query": "查询" "query": "查询",
"search": "搜索"
} }

View File

@ -82,6 +82,7 @@ const gridOptions: VxeGridProps<RowType> = {
}, },
}, },
}, },
showOverflow: false,
}; };
const [Grid] = useVbenVxeGrid({ gridOptions }); const [Grid] = useVbenVxeGrid({ gridOptions });

View File

@ -1,6 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { VbenFormProps } from '#/adapter/form'; import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table'; import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import { Page } from '@vben/common-ui'; import { Page } from '@vben/common-ui';
@ -71,7 +71,7 @@ const formOptions: VbenFormProps = {
submitOnEnter: false, submitOnEnter: false,
}; };
const gridOptions: VxeGridProps<RowType> = { const gridOptions: VxeTableGridOptions<RowType> = {
checkboxConfig: { checkboxConfig: {
highlight: true, highlight: true,
labelField: 'name', labelField: 'name',
@ -85,6 +85,7 @@ const gridOptions: VxeGridProps<RowType> = {
{ field: 'price', title: 'Price' }, { field: 'price', title: 'Price' },
{ field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' }, { field: 'releaseDate', formatter: 'formatDateTime', title: 'Date' },
], ],
exportConfig: {},
height: 'auto', height: 'auto',
keepSource: true, keepSource: true,
pagerConfig: {}, pagerConfig: {},
@ -100,9 +101,20 @@ const gridOptions: VxeGridProps<RowType> = {
}, },
}, },
}, },
toolbarConfig: {
custom: true,
export: true,
refresh: true,
resizable: true,
search: true,
zoom: true,
},
}; };
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions }); const [Grid] = useVbenVxeGrid({
formOptions,
gridOptions,
});
</script> </script>
<template> <template>