useTable.ts 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. import { Table, TableExpose } from '@/components/Table'
  2. import { ElTable, ElMessageBox, ElMessage } from 'element-plus'
  3. import { ref, reactive, watch, computed, unref, nextTick } from 'vue'
  4. import { AxiosPromise } from 'axios'
  5. import { get } from 'lodash-es'
  6. import type { TableProps } from '@/components/Table/src/types'
  7. import { useI18n } from '@/hooks/web/useI18n'
  8. const { t } = useI18n()
  9. interface UseTableConfig<T, L> {
  10. getListApi: (option: L) => AxiosPromise<T>
  11. delListApi?: (option: AxiosConfig) => AxiosPromise<unknown>
  12. // 返回数据格式配置
  13. response: {
  14. list: string
  15. total?: string
  16. }
  17. props?: TableProps
  18. }
  19. interface TableObject<K, L> {
  20. pageSize: number
  21. currentPage: number
  22. total: number
  23. tableList: K[]
  24. parmasObj: L
  25. loading: boolean
  26. currentRow: Nullable<K>
  27. }
  28. export const useTable = <T, K, L extends AxiosConfig = AxiosConfig>(
  29. config?: UseTableConfig<T, L>
  30. ) => {
  31. const tableObject = reactive<TableObject<K, L>>({
  32. // 页数
  33. pageSize: 10,
  34. // 当前页
  35. currentPage: 1,
  36. // 总条数
  37. total: 10,
  38. // 表格数据
  39. tableList: [],
  40. // AxiosConfig 配置
  41. parmasObj: {} as L,
  42. // 加载中
  43. loading: true,
  44. // 当前行的数据
  45. currentRow: null
  46. })
  47. const parmasObj = computed(() => {
  48. return {
  49. params: {
  50. ...tableObject.parmasObj.params,
  51. pageSize: tableObject.pageSize,
  52. pageIndex: tableObject.currentPage
  53. }
  54. }
  55. })
  56. watch(
  57. () => tableObject.currentPage,
  58. () => {
  59. methods.getList()
  60. }
  61. )
  62. watch(
  63. () => tableObject.pageSize,
  64. () => {
  65. tableObject.currentPage = 1
  66. methods.getList()
  67. }
  68. )
  69. // Table实例
  70. const tableRef = ref<typeof Table & TableExpose>()
  71. // ElTable实例
  72. const elTableRef = ref<ComponentRef<typeof ElTable>>()
  73. const register = (ref: typeof Table & TableExpose, elRef: ComponentRef<typeof ElTable>) => {
  74. tableRef.value = ref
  75. elTableRef.value = elRef
  76. }
  77. const getTable = async () => {
  78. await nextTick()
  79. const table = unref(tableRef)
  80. if (!table) {
  81. console.error('The table is not registered. Please use the register method to register')
  82. }
  83. return table
  84. }
  85. const delData = async (paramsObj: AxiosConfig, ids: string[] | number[]) => {
  86. const res = await (config?.delListApi && config?.delListApi(paramsObj))
  87. if (res) {
  88. ElMessage.success(t('common.delSuccess'))
  89. // 计算出临界点
  90. const currentPage =
  91. tableObject.total % tableObject.pageSize === ids.length || tableObject.pageSize === 1
  92. ? tableObject.currentPage > 1
  93. ? tableObject.currentPage - 1
  94. : tableObject.currentPage
  95. : tableObject.currentPage
  96. tableObject.currentPage = currentPage
  97. methods.getList()
  98. }
  99. }
  100. const methods: {
  101. setProps: (props: Recordable) => void
  102. getList: () => Promise<void>
  103. setColumn: (columnProps: TableSetPropsType[]) => void
  104. setSearchParmas: (data: Recordable) => void
  105. getSelections: () => Promise<K[]>
  106. delList: (ids: string[] | number[], multiple: boolean, message?: boolean) => Promise<void>
  107. } = {
  108. getList: async () => {
  109. tableObject.loading = true
  110. const res = await config
  111. ?.getListApi(unref(parmasObj) as unknown as L)
  112. .catch(() => {})
  113. .finally(() => {
  114. tableObject.loading = false
  115. })
  116. if (res) {
  117. tableObject.tableList = get(res.data || {}, config?.response.list as string)
  118. tableObject.total = get(res.data || {}, config?.response?.total as string) || 0
  119. }
  120. },
  121. setProps: async (props: TableProps = {}) => {
  122. const table = await getTable()
  123. table?.setProps(props)
  124. },
  125. setColumn: async (columnProps: TableSetPropsType[]) => {
  126. const table = await getTable()
  127. table?.setColumn(columnProps)
  128. },
  129. getSelections: async () => {
  130. const table = await getTable()
  131. return (table?.selections || []) as K[]
  132. },
  133. // 与Search组件结合
  134. setSearchParmas: (data: Recordable) => {
  135. tableObject.currentPage = 1
  136. tableObject.parmasObj = Object.assign(tableObject.parmasObj, {
  137. params: {
  138. pageSize: tableObject.pageSize,
  139. pageIndex: tableObject.currentPage,
  140. ...data
  141. }
  142. })
  143. methods.getList()
  144. },
  145. // 删除数据
  146. delList: async (ids: string[] | number[], multiple: boolean, message = true) => {
  147. const tableRef = await getTable()
  148. if (multiple) {
  149. if (!tableRef?.selections.length) {
  150. ElMessage.warning(t('common.delNoData'))
  151. return
  152. }
  153. } else {
  154. if (!tableObject.currentRow) {
  155. ElMessage.warning(t('common.delNoData'))
  156. return
  157. }
  158. }
  159. const paramsObj: AxiosConfig = {
  160. data: {
  161. ids
  162. }
  163. }
  164. if (message) {
  165. ElMessageBox.confirm(t('common.delMessage'), t('common.delWarning'), {
  166. confirmButtonText: t('common.delOk'),
  167. cancelButtonText: t('common.delCancel'),
  168. type: 'warning'
  169. })
  170. .then(async () => {
  171. await delData(paramsObj, ids)
  172. })
  173. .catch(() => {})
  174. } else {
  175. await delData(paramsObj, ids)
  176. }
  177. }
  178. }
  179. config?.props && methods.setProps(config.props)
  180. return {
  181. register,
  182. elTableRef,
  183. tableObject,
  184. methods
  185. }
  186. }