Forráskód Böngészése

使用组合式函数重构proTable组件

tongshangming 2 éve
szülő
commit
137152f9b6
3 módosított fájl, 248 hozzáadás és 206 törlés
  1. 38 206
      src/components/core/ProTable.vue
  2. 161 0
      src/hooks/useTable.ts
  3. 49 0
      src/hooks/useTableQuery.ts

+ 38 - 206
src/components/core/ProTable.vue

@@ -1,16 +1,14 @@
-<script lang="ts">
-export default {
+<script setup lang="ts">
+defineOptions({
   inheritAttrs: false
-}
-</script>
+})
 
-<script setup lang="ts">
-import router from '@/router'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import type { DialogProps, DrawerProps } from 'element-plus'
-import type { BasicForm, BasicFormItem, ICRUD, FormSlot } from '@/types/form'
-import type { VXEComponent, VxeToolbarProps, VxeToolbarEventProps, VxeToolbarPropTypes } from 'vxe-table'
 import { buildFormSlots } from '@/utils/utils'
+import { useTableQuery } from '@/hooks/useTableQuery'
+import { useTable } from '@/hooks/useTable'
+import type { DialogProps, DrawerProps } from 'element-plus'
+import type { BasicForm, ICRUD, FormSlot } from '@/types/form'
+import type { VxeToolbarProps } from 'vxe-table'
 
 interface CustomTable {
   showOperate?: boolean
@@ -41,53 +39,31 @@ const props = withDefaults(defineProps<Props>(), {
   showToolbar: true,
   formMode: 'dialog'
 })
-
-const emits = defineEmits(['click-create', 'click-edit', 'click-view', 'click-reset', 'checkbox-change'])
-
+const emits = defineEmits(['click-create', 'click-edit', 'click-view', 'checkbox-change', 'click-reset'])
 const slots = useSlots()
 
 // ============== 查询部分开始 ===============
-const query = ref<any>({})
-const defaultQuery = ref<any>({})
-const searchList = ref<any>([])
-// 构造搜索列表
-const buildSearchList = (item: BasicFormItem) => {
-  if (item.search) {
-    searchList.value.push(Object.assign({}, item, { props: { ...item.props, disabled: false } }))
-    if (item.value) {
-      query.value[item.name] = item.value
-      defaultQuery.value[item.name] = item.value
-    }
-  }
-  item.children && item.children.forEach(buildSearchList)
-}
-watch(
-  () => props.formConfig.formItems,
-  val => {
-    searchList.value = []
-    val.forEach((item: BasicFormItem) => {
-      buildSearchList(item)
-    })
-  },
-  { immediate: true }
-)
-
-const handleQuery = () => {
-  curPage.value = 1
-  getTableData()
-}
-const handleReset = () => {
-  query.value = { ...defaultQuery.value }
-  emits('click-reset', query.value)
-  handleQuery()
-}
+const { query, searchList, handleQuery, handleReset } = useTableQuery(props, emits)
 // ============== 查询部分结束 ===============
 
 // ============== 表格部分开始 ===============
-const tableData = ref([])
-const total = ref(0)
-const curPage = ref(1)
-const loading = ref(false)
+const {
+  tableData,
+  formData,
+  getTableData,
+  total,
+  curPage,
+  loading,
+  formVisible,
+  multipleSelection,
+  refresh,
+  handleCreate,
+  handleDelete,
+  handleBatchDelete,
+  handleUpdate,
+  handleView
+} = useTable(props, emits)
+
 const tableConfig = computed<CustomTable>(() => ({
   showOperate: true,
   showView: false,
@@ -99,7 +75,6 @@ const tableConfig = computed<CustomTable>(() => ({
 
 const xTable = ref<any>()
 const xToolbar = ref<any>()
-
 nextTick(() => {
   // 将表格和工具栏进行关联
   const $table = xTable.value
@@ -107,163 +82,10 @@ nextTick(() => {
   $toolbar && $table.connect($toolbar)
 })
 
-const getTableData = () => {
-  loading.value = true
-  props.crud
-    ?.getList({
-      ...query.value,
-      pageSize: props.pageSize,
-      pageNo: curPage.value
-    })
-    .then((res: any) => {
-      tableData.value = res.list || res.rows || res.infos
-      total.value = res.total || res.totalCount
-    })
-    .finally(() => {
-      loading.value = false
-    })
-}
-
-watch(
-  curPage,
-  () => {
-    getTableData()
-  },
-  {
-    immediate: true
-  }
-)
-
-const refresh = () => {
-  curPage.value = 1
-  getTableData()
-}
-
-const multipleSelection = ref<any[]>([])
 const handleSelectionChange = () => {
   multipleSelection.value = xTable.value.getCheckboxRecords()
   emits('checkbox-change', multipleSelection.value)
 }
-// ============== 表格部分结束 ===============
-
-// ============== crud部分开始 ===============
-const formRoute = ref<any>(props.formConfig.route)
-
-const doCreate = () => {
-  emits('click-create')
-  if (formRoute.value) {
-    router.push(formRoute.value)
-  } else {
-    formData.value = {}
-    props.formConfig.disabled = false
-    formVisible.value = true
-  }
-}
-const handleCreate = async () => {
-  if (!props.beforeCreate) {
-    return doCreate()
-  }
-
-  let result = true
-  try {
-    const beforeUploadPromise = props.beforeCreate(formData.value)
-    result = await beforeUploadPromise
-  } catch {
-    result = false
-  }
-
-  if (result === false) {
-    return
-  }
-  doCreate()
-}
-
-const handleUpdate = (row: any) => {
-  emits('click-edit', row)
-  if (formRoute.value) {
-    router.push(formRoute.value)
-  } else {
-    if (props.crud?.getRecord) {
-      props.crud.getRecord({ id: row.id }).then((res: any) => {
-        formData.value = res.data
-      })
-    } else {
-      formData.value = { ...row }
-    }
-    props.formConfig.disabled = false
-    formVisible.value = true
-  }
-}
-const handleView = (row: any) => {
-  emits('click-view', row)
-  if (formRoute.value) {
-    router.push(formRoute.value)
-  } else {
-    if (props.crud?.getRecord) {
-      props.crud.getRecord({ id: row.id }).then((res: any) => {
-        formData.value = res.data
-      })
-    } else {
-      formData.value = { ...row }
-    }
-    props.formConfig.disabled = true
-    formVisible.value = true
-  }
-}
-const handleDelete = (id: string | number) => {
-  ElMessageBox.confirm('您确定要删除该项吗', '提示', {
-    type: 'warning'
-  }).then(async () => {
-    const data = await props.crud?.delete({ id })
-    if (data.success || data.code === 200) {
-      getTableData()
-      ElMessage({
-        type: 'success',
-        message: '删除成功'
-      })
-    } else {
-      ElMessage.error(data.msg)
-    }
-  })
-}
-const handleBatchDelete = () => {
-  ElMessageBox.confirm('您确定要删除吗', '提示', {
-    type: 'warning'
-  }).then(async () => {
-    if (props.crud.deleteBatch) {
-      const data = await props.crud?.deleteBatch({
-        ids: multipleSelection.value.map(item => item.id).join(',')
-      })
-      if (data.success || data.code === 200) {
-        getTableData()
-        ElMessage({
-          type: 'success',
-          message: '删除成功'
-        })
-      } else {
-        ElMessage.error(data.msg)
-      }
-    } else {
-      ElMessage({
-        type: 'error',
-        message: '未提供deleteBatch方法'
-      })
-    }
-  })
-}
-// ============== crud部分结束 ===============
-
-// ============== 表单部分开始 ===============
-const formData = ref<any>({})
-const formVisible = ref(false)
-const handleFormSuccess = () => {
-  getTableData()
-}
-
-// 构造表单插槽
-const formSlots = ref<FormSlot[]>([])
-buildFormSlots(props.formConfig.formItems, formSlots.value)
-// ============== 表单部分结束 ===============
 
 // 动态计算table高度
 const toolbarRef = ref<any>(null)
@@ -275,7 +97,6 @@ const calcHeight = () => {
   const paginationHeight = paginationRef.value ? paginationRef.value.offsetHeight : 0
   tableHeight.value = `calc(100% - ${toolbarHeight + paginationHeight}px)`
 }
-
 nextTick(() => {
   calcHeight()
 })
@@ -287,6 +108,17 @@ watch(
     })
   }
 )
+// ============== 表格部分结束 ===============
+
+// ============== 表单部分开始 ===============
+const handleFormSuccess = () => {
+  getTableData()
+}
+
+// 构造表单插槽
+const formSlots = ref<FormSlot[]>([])
+buildFormSlots(props.formConfig.formItems, formSlots.value)
+// ============== 表单部分结束 ===============
 
 defineExpose({
   handleCreate,

+ 161 - 0
src/hooks/useTable.ts

@@ -0,0 +1,161 @@
+import router from '@/router'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+export const useTable = (props: any, emits: any) => {
+  const loading = ref(false)
+  const tableData = ref<any>([])
+  const total = ref(0)
+  const curPage = ref(1)
+  /**
+   * 获取表格数据
+   * @param query - 查询参数
+   */
+  const getTableData = (query?: any) => {
+    loading.value = true
+    props.crud
+      ?.getList({
+        ...query,
+        pageSize: props.pageSize,
+        pageNo: curPage.value
+      })
+      .then((res: any) => {
+        tableData.value = res.infos || res.list || res.rows
+        total.value = res.total || res.totalCount
+      })
+      .finally(() => {
+        loading.value = false
+      })
+  }
+  watch(
+    curPage,
+    () => {
+      getTableData()
+    },
+    {
+      immediate: true
+    }
+  )
+
+  const refresh = () => {
+    curPage.value = 1
+    getTableData()
+  }
+
+  // ============== crud部分开始 ===============
+  const formRoute = ref<any>(props.formConfig.route)
+  const formData = ref<any>({})
+  const formVisible = ref(false)
+
+  const doCreate = () => {
+    emits('click-create')
+    if (formRoute.value) {
+      router.push(formRoute.value)
+    } else {
+      formData.value = {}
+      props.formConfig.disabled = false
+      formVisible.value = true
+    }
+  }
+  const handleCreate = async () => {
+    if (!props.beforeCreate) {
+      return doCreate()
+    }
+
+    let result = true
+    try {
+      const beforeUploadPromise = props.beforeCreate(formData.value)
+      result = await beforeUploadPromise
+    } catch {
+      result = false
+    }
+
+    if (result === false) {
+      return
+    }
+    doCreate()
+  }
+
+  // 编辑、查看
+  const useRecordData = (row: any, disabled: boolean) => {
+    // 此函数用于获取记录数据并设置相应的表单配置
+    if (formRoute.value) {
+      router.push(formRoute.value)
+    } else {
+      if (props.crud?.getRecord) {
+        props.crud.getRecord({ id: row.id }).then((res: any) => {
+          formData.value = res.data
+        })
+      } else {
+        formData.value = { ...row }
+      }
+      props.formConfig.disabled = disabled
+      formVisible.value = true
+    }
+  }
+  const handleUpdate = (row: any) => {
+    emits('click-edit', row)
+    useRecordData(row, false)
+  }
+  const handleView = (row: any) => {
+    emits('click-view', row)
+    useRecordData(row, true)
+  }
+
+  // 删除成功
+  const deleteSuccess = (data: any) => {
+    if (data.success || data.code === 200) {
+      getTableData()
+      ElMessage({
+        type: 'success',
+        message: '删除成功'
+      })
+    } else {
+      ElMessage.error(data.msg)
+    }
+  }
+  const handleDelete = (id: string | number) => {
+    ElMessageBox.confirm('您确定要删除该项吗', '提示', {
+      type: 'warning'
+    }).then(async () => {
+      const data = await props.crud?.delete({ id })
+      deleteSuccess(data)
+    })
+  }
+
+  const multipleSelection = ref<any[]>([])
+  const handleBatchDelete = () => {
+    ElMessageBox.confirm('您确定要删除吗', '提示', {
+      type: 'warning'
+    }).then(async () => {
+      if (props.crud.deleteBatch) {
+        const data = await props.crud?.deleteBatch({
+          ids: multipleSelection.value.map(item => item.id).join(',')
+        })
+        deleteSuccess(data)
+      } else {
+        ElMessage({
+          type: 'error',
+          message: '未提供deleteBatch方法'
+        })
+      }
+    })
+  }
+  // ============== crud部分结束 ===============
+
+  return {
+    tableData,
+    total,
+    curPage,
+    loading,
+    formData,
+    formVisible,
+    multipleSelection,
+    getTableData,
+    refresh,
+    handleCreate,
+    handleDelete,
+    handleBatchDelete,
+    handleUpdate,
+    handleView
+  }
+}

+ 49 - 0
src/hooks/useTableQuery.ts

@@ -0,0 +1,49 @@
+import { useTable } from './useTable'
+import type { BasicFormItem } from '@/types/form'
+
+export const useTableQuery = (props: any, emits: any) => {
+  const query = ref<any>({})
+  const defaultQuery = ref<any>({})
+  const searchList = ref<any>([])
+  // 构造搜索列表
+  const buildSearchList = (item: BasicFormItem) => {
+    if (item.search) {
+      searchList.value.push(Object.assign({}, item, { props: { ...item.props, disabled: false } }))
+      if (item.value) {
+        query.value[item.name] = item.value
+        defaultQuery.value[item.name] = item.value
+      }
+    }
+    if (item.children) {
+      item.children.forEach(buildSearchList)
+    }
+  }
+  watch(
+    () => props.formConfig.formItems,
+    val => {
+      searchList.value = []
+      val.forEach((item: BasicFormItem) => {
+        buildSearchList(item)
+      })
+    },
+    { immediate: true }
+  )
+
+  const { curPage, getTableData } = useTable(props, emits)
+  const handleQuery = () => {
+    curPage.value = 1
+    getTableData(query.value)
+  }
+  const handleReset = () => {
+    query.value = { ...defaultQuery.value }
+    emits('click-reset', query.value)
+    handleQuery()
+  }
+
+  return {
+    query,
+    searchList,
+    handleQuery,
+    handleReset
+  }
+}