feat: table search form visible control (#5121)
* feat: table search form visible control * chore: fix docs and demo * chore: type error fixedpull/60/MERGE
							parent
							
								
									d308da6ba1
								
							
						
					
					
						commit
						ed465d2b5b
					
				|  | @ -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`           | | ||||||
|  |  | ||||||
|  | @ -110,6 +110,11 @@ const gridOptions: VxeGridProps<RowType> = { | ||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   toolbarConfig: { | ||||||
|  |     // 是否显示搜索表单控制按钮 | ||||||
|  |     // @ts-ignore 正式环境时有完整的类型声明 | ||||||
|  |     search: true, | ||||||
|  |   }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const [Grid] = useVbenVxeGrid({ formOptions, gridOptions }); | const [Grid] = useVbenVxeGrid({ formOptions, gridOptions }); | ||||||
|  |  | ||||||
|  | @ -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(); | ||||||
|  |  | ||||||
|  | @ -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'; | ||||||
|  |  | ||||||
|  | @ -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 = { | ||||||
|  |  | ||||||
|  | @ -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: { |  | ||||||
|       slots: { |  | ||||||
|     ...(slotActions || showTableTitle.value |     ...(slotActions || showTableTitle.value | ||||||
|       ? { buttons: TOOLBAR_ACTIONS } |       ? { 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 | ||||||
|  |  | ||||||
|  | @ -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" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -9,5 +9,6 @@ | ||||||
|   "noData": "暂无数据", |   "noData": "暂无数据", | ||||||
|   "refresh": "刷新", |   "refresh": "刷新", | ||||||
|   "loadingMenu": "加载菜单中", |   "loadingMenu": "加载菜单中", | ||||||
|   "query": "查询" |   "query": "查询", | ||||||
|  |   "search": "搜索" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -82,6 +82,7 @@ const gridOptions: VxeGridProps<RowType> = { | ||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   showOverflow: false, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| const [Grid] = useVbenVxeGrid({ gridOptions }); | const [Grid] = useVbenVxeGrid({ gridOptions }); | ||||||
|  |  | ||||||
|  | @ -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> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Netfan
						Netfan