mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	feat: 完善xtable组件
This commit is contained in:
		| @ -12,6 +12,12 @@ import { useAppStore } from '@/store/modules/app' | |||||||
| import { useDesign } from '@/hooks/web/useDesign' | import { useDesign } from '@/hooks/web/useDesign' | ||||||
| import { XTableProps } from './type' | import { XTableProps } from './type' | ||||||
| import { isBoolean, isFunction } from '@/utils/is' | import { isBoolean, isFunction } from '@/utils/is' | ||||||
|  | import { useMessage } from '@/hooks/web/useMessage' | ||||||
|  | import download from '@/utils/download' | ||||||
|  | import { useI18n } from '@/hooks/web/useI18n' | ||||||
|  |  | ||||||
|  | const { t } = useI18n() | ||||||
|  | const message = useMessage() // 消息弹窗 | ||||||
|  |  | ||||||
| const appStore = useAppStore() | const appStore = useAppStore() | ||||||
|  |  | ||||||
| @ -21,30 +27,6 @@ const prefixCls = getPrefixCls('x-vxe-table') | |||||||
| const attrs = useAttrs() | const attrs = useAttrs() | ||||||
| const emit = defineEmits(['register']) | const emit = defineEmits(['register']) | ||||||
|  |  | ||||||
| const props = defineProps({ |  | ||||||
|   options: { |  | ||||||
|     type: Object as PropType<XTableProps>, |  | ||||||
|     default: () => {} |  | ||||||
|   } |  | ||||||
| }) |  | ||||||
| const innerProps = ref<Partial<XTableProps>>() |  | ||||||
|  |  | ||||||
| const getProps = computed(() => { |  | ||||||
|   const options = innerProps.value || props.options |  | ||||||
|   options.size = currentSize as any |  | ||||||
|   options.height = 700 |  | ||||||
|   getColumnsConfig(options) |  | ||||||
|   getProxyConfig(options) |  | ||||||
|   getPageConfig(options) |  | ||||||
|   getToolBarConfig(options) |  | ||||||
|   // console.log(options); |  | ||||||
|   return { |  | ||||||
|     ...options, |  | ||||||
|     ...attrs |  | ||||||
|   } |  | ||||||
| }) |  | ||||||
|  |  | ||||||
| const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref |  | ||||||
| watch( | watch( | ||||||
|   () => appStore.getIsDark, |   () => appStore.getIsDark, | ||||||
|   () => { |   () => { | ||||||
| @ -57,6 +39,7 @@ watch( | |||||||
|   }, |   }, | ||||||
|   { immediate: true } |   { immediate: true } | ||||||
| ) | ) | ||||||
|  |  | ||||||
| const currentSize = computed(() => { | const currentSize = computed(() => { | ||||||
|   let resSize: SizeType = 'small' |   let resSize: SizeType = 'small' | ||||||
|   const appsize = appStore.getCurrentSize |   const appsize = appStore.getCurrentSize | ||||||
| @ -74,25 +57,42 @@ const currentSize = computed(() => { | |||||||
|   return resSize |   return resSize | ||||||
| }) | }) | ||||||
|  |  | ||||||
| const reload = () => { | const props = defineProps({ | ||||||
|   const g = unref(xGrid) |   options: { | ||||||
|   if (!g) { |     type: Object as PropType<XTableProps>, | ||||||
|     return |     default: () => {} | ||||||
|   } |   } | ||||||
|   g.commitProxy('query') | }) | ||||||
| } | const innerProps = ref<Partial<XTableProps>>() | ||||||
|  |  | ||||||
| const getSearchData = () => { | const getProps = computed(() => { | ||||||
|   const g = unref(xGrid) |   const options = innerProps.value || props.options | ||||||
|   if (!g) { |   options.size = currentSize as any | ||||||
|     return |   options.height = 700 | ||||||
|  |   getOptionInitConfig(options) | ||||||
|  |   getColumnsConfig(options) | ||||||
|  |   getProxyConfig(options) | ||||||
|  |   getPageConfig(options) | ||||||
|  |   getToolBarConfig(options) | ||||||
|  |   // console.log(options); | ||||||
|  |   return { | ||||||
|  |     ...options, | ||||||
|  |     ...attrs | ||||||
|   } |   } | ||||||
|   const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form))) | }) | ||||||
|   return queryParams |  | ||||||
| } | const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref | ||||||
|  |  | ||||||
| let proxyForm = false | let proxyForm = false | ||||||
|  |  | ||||||
|  | const getOptionInitConfig = (options: XTableProps) => { | ||||||
|  |   options.size = currentSize as any | ||||||
|  |   options.rowConfig = { | ||||||
|  |     isCurrent: true, // 当鼠标点击行时,是否要高亮当前行 | ||||||
|  |     isHover: true // 当鼠标移到行时,是否要高亮当前行 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| // columns | // columns | ||||||
| const getColumnsConfig = (options: XTableProps) => { | const getColumnsConfig = (options: XTableProps) => { | ||||||
|   const { allSchemas } = options |   const { allSchemas } = options | ||||||
| @ -131,21 +131,55 @@ const getProxyConfig = (options: XTableProps) => { | |||||||
|           if (options.params) { |           if (options.params) { | ||||||
|             queryParams = Object.assign(queryParams, options.params) |             queryParams = Object.assign(queryParams, options.params) | ||||||
|           } |           } | ||||||
|           queryParams.pageSize = page.currentPage |           if (!options?.treeConfig) { | ||||||
|           queryParams.page = page.pageSize |             queryParams.pageSize = page.pageSize | ||||||
|  |             queryParams.pageNo = page.currentPage | ||||||
|  |           } | ||||||
|           return new Promise(async (resolve) => { |           return new Promise(async (resolve) => { | ||||||
|             resolve(await getListApi(queryParams)) |             resolve(await getListApi(queryParams)) | ||||||
|           }) |           }) | ||||||
|  |         }, | ||||||
|  |         delete: ({ body }) => { | ||||||
|  |           return new Promise(async (resolve) => { | ||||||
|  |             if (options.deleteApi) { | ||||||
|  |               resolve(await options.deleteApi(JSON.stringify(body))) | ||||||
|  |             } else { | ||||||
|  |               Promise.reject('未设置deleteApi') | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         }, | ||||||
|  |         queryAll: ({ form }) => { | ||||||
|  |           const queryParams = Object.assign({}, JSON.parse(JSON.stringify(form))) | ||||||
|  |           return new Promise(async (resolve) => { | ||||||
|  |             if (options.getAllListApi) { | ||||||
|  |               resolve(await options.getAllListApi(queryParams)) | ||||||
|  |             } else { | ||||||
|  |               resolve(await getListApi(queryParams)) | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |   if (options.exportListApi) { | ||||||
|  |     options.exportConfig = { | ||||||
|  |       filename: options?.exportName, | ||||||
|  |       // 默认选中类型 | ||||||
|  |       type: 'csv', | ||||||
|  |       // 自定义数据量列表 | ||||||
|  |       modes: options?.getAllListApi ? ['current', 'all'] : ['current'], | ||||||
|  |       columns: options?.allSchemas?.printSchema | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| // 分页 | // 分页 | ||||||
| const getPageConfig = (options: XTableProps) => { | const getPageConfig = (options: XTableProps) => { | ||||||
|   const { pagination, pagerConfig } = options |   const { pagination, pagerConfig, treeConfig } = options | ||||||
|  |   if (treeConfig) { | ||||||
|  |     options.treeConfig = options.treeConfig | ||||||
|  |     return | ||||||
|  |   } | ||||||
|   if (pagerConfig) return |   if (pagerConfig) return | ||||||
|   if (pagination) { |   if (pagination) { | ||||||
|     if (isBoolean(pagination)) { |     if (isBoolean(pagination)) { | ||||||
| @ -171,6 +205,28 @@ const getPageConfig = (options: XTableProps) => { | |||||||
|       return |       return | ||||||
|     } |     } | ||||||
|     options.pagerConfig = pagination |     options.pagerConfig = pagination | ||||||
|  |   } else { | ||||||
|  |     if (pagination != false) { | ||||||
|  |       options.pagerConfig = { | ||||||
|  |         border: false, // 带边框 | ||||||
|  |         background: true, // 带背景颜色 | ||||||
|  |         perfect: false, // 配套的样式 | ||||||
|  |         pageSize: 10, // 每页大小 | ||||||
|  |         pagerCount: 7, // 显示页码按钮的数量 | ||||||
|  |         autoHidden: false, // 当只有一页时自动隐藏 | ||||||
|  |         pageSizes: [5, 10, 20, 30, 50, 100], // 每页大小选项列表 | ||||||
|  |         layouts: [ | ||||||
|  |           'PrevJump', | ||||||
|  |           'PrevPage', | ||||||
|  |           'JumpNumber', | ||||||
|  |           'NextPage', | ||||||
|  |           'NextJump', | ||||||
|  |           'Sizes', | ||||||
|  |           'FullJump', | ||||||
|  |           'Total' | ||||||
|  |         ] | ||||||
|  |       } | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -190,12 +246,70 @@ const getToolBarConfig = (options: XTableProps) => { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // 刷新列表 | ||||||
|  | const reload = () => { | ||||||
|  |   const g = unref(xGrid) | ||||||
|  |   if (!g) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   g.commitProxy('query') | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 删除 | ||||||
|  | const deleteData = async (ids: string | number) => { | ||||||
|  |   const g = unref(xGrid) | ||||||
|  |   if (!g) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   const options = innerProps.value || props.options | ||||||
|  |   if (!options.deleteApi) { | ||||||
|  |     console.error('未传入delListApi') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   return new Promise(async () => { | ||||||
|  |     message.delConfirm().then(async () => { | ||||||
|  |       await (options?.deleteApi && options?.deleteApi(ids)) | ||||||
|  |       message.success(t('common.delSuccess')) | ||||||
|  |       // 刷新列表 | ||||||
|  |       reload() | ||||||
|  |     }) | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 导出 | ||||||
|  | const exportList = async (fileName?: string) => { | ||||||
|  |   const g = unref(xGrid) | ||||||
|  |   if (!g) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   const options = innerProps.value || props.options | ||||||
|  |   if (!options?.exportListApi) { | ||||||
|  |     console.error('未传入exportListApi') | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form))) | ||||||
|  |   message.exportConfirm().then(async () => { | ||||||
|  |     const res = await (options?.exportListApi && options?.exportListApi(queryParams)) | ||||||
|  |     download.excel(res as unknown as Blob, fileName ? fileName : 'excel.xls') | ||||||
|  |   }) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 获取查询参数 | ||||||
|  | const getSearchData = () => { | ||||||
|  |   const g = unref(xGrid) | ||||||
|  |   if (!g) { | ||||||
|  |     return | ||||||
|  |   } | ||||||
|  |   const queryParams = Object.assign({}, JSON.parse(JSON.stringify(g.getProxyInfo()?.form))) | ||||||
|  |   return queryParams | ||||||
|  | } | ||||||
|  |  | ||||||
| const setProps = (prop: Partial<XTableProps>) => { | const setProps = (prop: Partial<XTableProps>) => { | ||||||
|   innerProps.value = { ...unref(innerProps), ...prop } |   innerProps.value = { ...unref(innerProps), ...prop } | ||||||
| } | } | ||||||
|  |  | ||||||
| defineExpose({ reload, Ref: xGrid, getSearchData }) | defineExpose({ reload, Ref: xGrid, getSearchData, deleteData, exportList }) | ||||||
| emit('register', { reload, getSearchData, setProps }) | emit('register', { reload, getSearchData, setProps, deleteData, exportList }) | ||||||
| </script> | </script> | ||||||
| <style lang="scss"> | <style lang="scss"> | ||||||
| @import './style/index.scss'; | @import './style/index.scss'; | ||||||
|  | |||||||
| @ -1,11 +1,16 @@ | |||||||
| import { CrudSchema } from '@/hooks/web/useCrudSchemas' | import { CrudSchema } from '@/hooks/web/useCrudSchemas' | ||||||
| import type { VxeGridProps, VxeGridPropTypes } from 'vxe-table' | import type { VxeGridProps, VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table' | ||||||
|  |  | ||||||
| export type XTableProps<D = any> = VxeGridProps<D> & { | export type XTableProps<D = any> = VxeGridProps<D> & { | ||||||
|   allSchemas?: CrudSchema |   allSchemas?: CrudSchema | ||||||
|  |   height?: number // 高度 默认730 | ||||||
|  |   topActionSlots?: boolean // 是否开启表格内顶部操作栏插槽 | ||||||
|  |   treeConfig?: VxeTablePropTypes.TreeConfig // 树形表单配置 | ||||||
|   getListApi?: Function |   getListApi?: Function | ||||||
|  |   getAllListApi?: Function | ||||||
|   deleteApi?: Function |   deleteApi?: Function | ||||||
|   exportListApi?: Function |   exportListApi?: Function | ||||||
|  |   exportName?: string // 导出文件夹名称 | ||||||
|   params?: any |   params?: any | ||||||
|   pagination?: boolean | VxeGridPropTypes.PagerConfig |   pagination?: boolean | VxeGridPropTypes.PagerConfig | ||||||
|   toolBar?: boolean | VxeGridPropTypes.ToolbarConfig |   toolBar?: boolean | VxeGridPropTypes.ToolbarConfig | ||||||
|  | |||||||
| @ -4,6 +4,8 @@ import { XTableProps } from '@/components/XTable/src/type' | |||||||
| export interface tableMethod { | export interface tableMethod { | ||||||
|   reload: () => void |   reload: () => void | ||||||
|   setProps: (props: XTableProps) => void |   setProps: (props: XTableProps) => void | ||||||
|  |   deleteData: (ids: string | number) => void | ||||||
|  |   exportList: (fileName?: string) => void | ||||||
| } | } | ||||||
|  |  | ||||||
| export function useXTable(props: XTableProps): [Function, tableMethod] { | export function useXTable(props: XTableProps): [Function, tableMethod] { | ||||||
| @ -22,7 +24,9 @@ export function useXTable(props: XTableProps): [Function, tableMethod] { | |||||||
|   } |   } | ||||||
|   const methods: tableMethod = { |   const methods: tableMethod = { | ||||||
|     reload: () => getInstance().reload(), |     reload: () => getInstance().reload(), | ||||||
|     setProps: (props) => getInstance().setProps(props) |     setProps: (props) => getInstance().setProps(props), | ||||||
|  |     deleteData: (ids: string | number) => getInstance().deleteData(ids), | ||||||
|  |     exportList: (fileName?: string) => getInstance().exportList(fileName) | ||||||
|   } |   } | ||||||
|   return [register, methods] |   return [register, methods] | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,9 +1,7 @@ | |||||||
| import { App, unref, watch } from 'vue' | import { App, unref } from 'vue' | ||||||
| import XEUtils from 'xe-utils' | import XEUtils from 'xe-utils' | ||||||
| import './index.scss' |  | ||||||
| import './renderer' | import './renderer' | ||||||
| import { i18n } from '@/plugins/vueI18n' | import { i18n } from '@/plugins/vueI18n' | ||||||
| import { useAppStore } from '@/store/modules/app' |  | ||||||
| import zhCN from 'vxe-table/lib/locale/lang/zh-CN' | import zhCN from 'vxe-table/lib/locale/lang/zh-CN' | ||||||
| import enUS from 'vxe-table/lib/locale/lang/en-US' | import enUS from 'vxe-table/lib/locale/lang/en-US' | ||||||
| import { | import { | ||||||
| @ -46,21 +44,6 @@ import { | |||||||
|   Table |   Table | ||||||
| } from 'vxe-table' | } from 'vxe-table' | ||||||
|  |  | ||||||
| const appStore = useAppStore() |  | ||||||
| watch( |  | ||||||
|   () => appStore.getIsDark, |  | ||||||
|   () => { |  | ||||||
|     if (appStore.getIsDark) { |  | ||||||
|       import('./theme/dark.scss') |  | ||||||
|     } else { |  | ||||||
|       import('./theme/light.scss') |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   { |  | ||||||
|     deep: true, |  | ||||||
|     immediate: true |  | ||||||
|   } |  | ||||||
| ) |  | ||||||
| // 全局默认参数 | // 全局默认参数 | ||||||
| VXETable.setup({ | VXETable.setup({ | ||||||
|   size: 'medium', // 全局尺寸 |   size: 'medium', // 全局尺寸 | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 xingyu
					xingyu