mirror of
				https://github.com/YunaiV/ruoyi-vue-pro.git
				synced 2025-10-31 18:49:06 +08:00 
			
		
		
		
	feat: add vxe-table
This commit is contained in:
		| @ -1,35 +1,185 @@ | |||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { PropType, reactive, ref } from 'vue' | import { PropType, reactive, ref } from 'vue' | ||||||
| import { VxeGrid, VxeGridProps, VxeTableInstance } from 'vxe-table' | import { propTypes } from '@/utils/propTypes' | ||||||
|  | import { VxeGrid, VxeGridProps, VXETable, VxeTableInstance } from 'vxe-table' | ||||||
|  | import XEUtils from 'xe-utils' | ||||||
|  |  | ||||||
| const props = defineProps({ | const props = defineProps({ | ||||||
|   options: { |   columns: { | ||||||
|     type: Object as PropType<VxeGridProps>, |     type: Array as PropType<any[]>, | ||||||
|     default: () => ({}) |     default: () => [] | ||||||
|   } |   }, | ||||||
|  |   form: { | ||||||
|  |     type: Array as PropType<any[]>, | ||||||
|  |     default: () => [] | ||||||
|  |   }, | ||||||
|  |   api: propTypes.string.def('') | ||||||
| }) | }) | ||||||
| const xGrid = ref<VxeTableInstance>() | const xGrid = ref<VxeTableInstance>() | ||||||
|  |  | ||||||
| const gridOptions = reactive<VxeGridProps>({ | const gridOptions = reactive<VxeGridProps>({ | ||||||
|   height: 300, |   id: 'crud', | ||||||
|  |   height: 600, | ||||||
|  |   showHeaderOverflow: true, | ||||||
|  |   showOverflow: true, | ||||||
|   align: null, |   align: null, | ||||||
|  |   loading: true, | ||||||
|   columnConfig: { |   columnConfig: { | ||||||
|     resizable: true |     resizable: true | ||||||
|   }, |   }, | ||||||
|  |   formConfig: { | ||||||
|  |     titleWidth: 100, | ||||||
|  |     titleAlign: 'right', | ||||||
|  |     items: [] | ||||||
|  |   }, | ||||||
|  |   pagerConfig: { | ||||||
|  |     pageSize: 10, | ||||||
|  |     pageSizes: [5, 10, 15, 20, 50, 100, 200, 500] | ||||||
|  |   }, | ||||||
|   columns: [], |   columns: [], | ||||||
|   toolbarConfig: {}, |   toolbarConfig: { | ||||||
|   data: [] |     buttons: [ | ||||||
|  |       { code: 'insert', name: '新增' }, | ||||||
|  |       { code: 'delete', name: '删除' }, | ||||||
|  |       { code: 'save', name: '保存', status: 'success' } | ||||||
|  |     ], | ||||||
|  |     refresh: true, | ||||||
|  |     import: true, | ||||||
|  |     export: true, | ||||||
|  |     print: true, | ||||||
|  |     zoom: true, | ||||||
|  |     custom: true | ||||||
|  |   }, | ||||||
|  |   importConfig: { | ||||||
|  |     remote: true, | ||||||
|  |     types: ['xlsx'], | ||||||
|  |     modes: ['insert'], | ||||||
|  |     // 自定义服务端导入 | ||||||
|  |     async importMethod({ file }) { | ||||||
|  |       const formBody = new FormData() | ||||||
|  |       formBody.append('file', file) | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`/api/pub/import`, { | ||||||
|  |           method: 'POST', | ||||||
|  |           body: formBody | ||||||
|  |         }) | ||||||
|  |         const data = await response.json() | ||||||
|  |         VXETable.modal.message({ | ||||||
|  |           content: `成功导入 ${data.result.insertRows} 条记录!`, | ||||||
|  |           status: 'success' | ||||||
|  |         }) | ||||||
|  |         // 导入完成,刷新表格 | ||||||
|  |         xGrid.value.commitProxy('query') | ||||||
|  |       } catch { | ||||||
|  |         VXETable.modal.message({ content: '导入失败,请检查数据是否正确!', status: 'error' }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   proxyConfig: { | ||||||
|  |     seq: true, // 启用动态序号代理,每一页的序号会根据当前页数变化 | ||||||
|  |     sort: true, // 启用排序代理,当点击排序时会自动触发 query 行为 | ||||||
|  |     filter: true, // 启用筛选代理,当点击筛选时会自动触发 query 行为 | ||||||
|  |     form: true, // 启用表单代理,当点击表单提交按钮时会自动触发 reload 行为 | ||||||
|  |     // 对应响应结果 { result: [], page: { total: 100 } } | ||||||
|  |     props: { | ||||||
|  |       result: 'result', // 配置响应结果列表字段 | ||||||
|  |       total: 'page.total' // 配置响应结果总页数字段 | ||||||
|  |     }, | ||||||
|  |     // 只接收Promise,具体实现自由发挥 | ||||||
|  |     ajax: { | ||||||
|  |       // 当点击工具栏查询按钮或者手动提交指令 query或reload 时会被触发 | ||||||
|  |       query: ({ page, sorts, filters, form }) => { | ||||||
|  |         const queryParams: any = Object.assign({}, form) | ||||||
|  |         // 处理排序条件 | ||||||
|  |         const firstSort = sorts[0] | ||||||
|  |         if (firstSort) { | ||||||
|  |           queryParams.sort = firstSort.field | ||||||
|  |           queryParams.order = firstSort.order | ||||||
|  |         } | ||||||
|  |         // 处理筛选条件 | ||||||
|  |         filters.forEach(({ field, values }) => { | ||||||
|  |           queryParams[field] = values.join(',') | ||||||
|  |         }) | ||||||
|  |         return fetch( | ||||||
|  |           props.api + `/list${page.pageSize}/${page.currentPage}?${XEUtils.serialize(queryParams)}` | ||||||
|  |         ).then((response) => response.json()) | ||||||
|  |       }, | ||||||
|  |       // 当点击工具栏删除按钮或者手动提交指令 delete 时会被触发 | ||||||
|  |       delete: ({ body }) => { | ||||||
|  |         return fetch(props.api + `/save`, { | ||||||
|  |           method: 'POST', | ||||||
|  |           headers: { 'Content-Type': 'application/json' }, | ||||||
|  |           body: JSON.stringify(body) | ||||||
|  |         }).then((response) => response.json()) | ||||||
|  |       }, | ||||||
|  |       // 当点击工具栏保存按钮或者手动提交指令 save 时会被触发 | ||||||
|  |       save: ({ body }) => { | ||||||
|  |         return fetch(props.api + `/save`, { | ||||||
|  |           method: 'POST', | ||||||
|  |           headers: { 'Content-Type': 'application/json' }, | ||||||
|  |           body: JSON.stringify(body) | ||||||
|  |         }).then((response) => response.json()) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   exportConfig: { | ||||||
|  |     remote: true, | ||||||
|  |     types: ['xlsx'], | ||||||
|  |     modes: ['current', 'selected', 'all'], | ||||||
|  |     // 自定义服务端导出 | ||||||
|  |     async exportMethod({ options }) { | ||||||
|  |       const $grid = xGrid.value | ||||||
|  |       const proxyInfo = $grid.getProxyInfo() | ||||||
|  |       // 传给服务端的参数 | ||||||
|  |       const body = { | ||||||
|  |         filename: options.filename, | ||||||
|  |         sheetName: options.sheetName, | ||||||
|  |         isHeader: options.isHeader, | ||||||
|  |         original: options.original, | ||||||
|  |         mode: options.mode, | ||||||
|  |         pager: proxyInfo ? proxyInfo.pager : null, | ||||||
|  |         ids: options.mode === 'selected' ? options.data.map((item) => item.id) : [], | ||||||
|  |         fields: options.columns.map((column) => { | ||||||
|  |           return { | ||||||
|  |             field: column.field, | ||||||
|  |             title: column.title | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       } | ||||||
|  |       // 开始服务端导出 | ||||||
|  |       try { | ||||||
|  |         const response = await fetch(`/api/pub/export`, { | ||||||
|  |           method: 'POST', | ||||||
|  |           headers: { 'Content-Type': 'application/json' }, | ||||||
|  |           body: JSON.stringify(body) | ||||||
|  |         }) | ||||||
|  |         const data = await response.json() | ||||||
|  |         if (data.id) { | ||||||
|  |           VXETable.modal.message({ content: '导出成功,开始下载', status: 'success' }) | ||||||
|  |           // 读取路径,请求文件 | ||||||
|  |           fetch(`/api/pub/export/download/${data.id}`).then((response_1) => { | ||||||
|  |             response_1.blob().then((blob) => { | ||||||
|  |               // 开始下载 | ||||||
|  |               VXETable.saveFile({ filename: '导出数据', type: 'xlsx', content: blob }) | ||||||
|  |             }) | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       } catch { | ||||||
|  |         VXETable.modal.message({ content: '导出失败!', status: 'error' }) | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
| }) | }) | ||||||
| const init = () => { | const init = () => { | ||||||
|   console.log(props.options) |   gridOptions.columns = props.columns | ||||||
|  |   gridOptions.formConfig.items = props.form | ||||||
|  |   gridOptions.loading = false | ||||||
| } | } | ||||||
| init() | init() | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
| <template> | <template> | ||||||
|   <ContentWrap> |   <vxe-grid ref="xGrid" v-bind="gridOptions" class="pro-table-scrollbar" /> | ||||||
|     <vxe-grid ref="xGrid" v-bind="gridOptions" show-footer class="pro-table-scrollbar" /> |  | ||||||
|   </ContentWrap> |  | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <style scoped> | <style scoped> | ||||||
|  | |||||||
| @ -72,7 +72,7 @@ VXETable.setup({ | |||||||
|     clearable: true |     clearable: true | ||||||
|   }, |   }, | ||||||
|   i18n: (key, args) => { |   i18n: (key, args) => { | ||||||
|     return unref(i18n.global.locale) === 'zh' |     return unref(i18n.global.locale) === 'zh-CN' | ||||||
|       ? XEUtils.toFormatString(XEUtils.get(zhCN, key), args) |       ? XEUtils.toFormatString(XEUtils.get(zhCN, key), args) | ||||||
|       : XEUtils.toFormatString(XEUtils.get(enUS, key), args) |       : XEUtils.toFormatString(XEUtils.get(enUS, key), args) | ||||||
|   } |   } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 xingyu
					xingyu