Ver Fonte

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

tongshangming há 2 anos atrás
pai
commit
b7f228427b
3 ficheiros alterados com 74 adições e 137 exclusões
  1. 65 128
      src/components/core/ProCardList.vue
  2. 3 8
      src/components/core/ProTable.vue
  3. 6 1
      src/hooks/useTable.ts

+ 65 - 128
src/components/core/ProCardList.vue

@@ -1,12 +1,13 @@
-<script lang="ts">
-export default {
+<script setup lang="ts">
+defineOptions({
   inheritAttrs: false
-}
-</script>
+})
 
-<script setup lang="ts">
+import { useForm } from '@/hooks/useForm'
+import { useTableQuery } from '@/hooks/useTableQuery'
+import { useTable } from '@/hooks/useTable'
 import router from '@/router'
-import { ElMessage, ElMessageBox, type DialogProps } from 'element-plus'
+import type { DialogProps, DrawerProps } from 'element-plus'
 import type { BasicForm, BasicFormItem, ICRUD } from '@/types/form'
 
 interface Props {
@@ -14,144 +15,56 @@ interface Props {
   pageSize?: number
   formConfig: BasicForm
   dialogConfig?: DialogProps
+  drawerConfig?: Partial<DrawerProps>
   height?: string
   cardHeight?: string
   showAdd?: boolean
   span?: number
+  formMode?: 'dialog' | 'drawer'
+  beforeCreate?: Function
 }
 
 const props = withDefaults(defineProps<Props>(), {
   pageSize: 12,
   showAdd: true,
   cardHeight: '206px',
-  span: 4
+  span: 4,
+  formMode: 'dialog'
 })
 
 const emits = defineEmits(['click-create', 'click-edit'])
 
 // ============== 查询部分开始 ===============
-const query = ref<any>({})
-const searchList = ref<any>([])
-// 构造搜索列表
-const buildSearchList = (item: BasicFormItem) => {
-  if (item.search) {
-    searchList.value.push(Object.assign({}, item, { props: { ...item.props, disabled: false } }))
-  }
-  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 = {}
-  handleQuery()
-}
+const { query, searchList, handleQuery, handleReset } = useTableQuery(props, emits)
 // ============== 查询部分结束 ===============
 
 // ============== 表格部分开始 ===============
-const tableData = ref<any>([])
-const total = ref(0)
-const curPage = ref(1)
-const loading = ref(false)
-
-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
-      total.value = res.total
-    })
-    .finally(() => {
-      loading.value = false
-    })
-}
-
-watch(
+const {
+  tableData,
+  formData,
+  getTableData,
+  loading,
+  total,
   curPage,
-  () => {
-    getTableData()
-  },
-  {
-    immediate: true
-  }
-)
-
-const refresh = () => {
-  curPage.value = 1
-  getTableData()
-}
+  formVisible,
+  refresh,
+  handleCreate,
+  handleDelete,
+  handleUpdate,
+  handleView,
+  handleFormSuccess
+} = useTable(props, emits)
 
 // ============== 表格部分结束 ===============
 
-// ============== crud部分开始 ===============
-const formRoute = ref<any>(props.formConfig.route)
-const handleCreate = () => {
-  emits('click-create')
-  if (formRoute.value) {
-    router.push(formRoute.value)
-  } else {
-    formData.value = {}
-    dialogVisible.value = true
-  }
-}
-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 }
-    }
-    dialogVisible.value = true
-  }
-}
-const handleDelete = (id: string | number) => {
-  ElMessageBox.confirm('您确定要删除该项吗', '提示', {
-    type: 'warning'
-  }).then(async () => {
-    await props.crud?.delete({ id })
-    getTableData()
-    ElMessage({
-      type: 'success',
-      message: '删除成功'
-    })
-  })
-}
-// ============== crud部分结束 ===============
-
-// ============== 表单部分开始 ===============
-const formData = ref<any>({})
-const dialogVisible = ref(false)
-const handleFormSuccess = () => {
-  getTableData()
-}
-// ============== 表单部分结束 ===============
+// 构造表单插槽
+const { formSlots } = useForm(props)
 
 defineExpose({
   handleCreate,
   handleDelete,
   handleUpdate,
+  handleView,
   refresh
 })
 </script>
@@ -175,7 +88,7 @@ defineExpose({
       <div class="flex flex-col h-full">
         <slot name="header"></slot>
 
-        <div class="h-full flex-grow">
+        <div class="h-full flex-grow" v-loading="loading">
           <el-row :gutter="10">
             <el-col :span="span" v-bind="$attrs" v-if="showAdd" class="mb-10">
               <div
@@ -206,16 +119,40 @@ defineExpose({
       </div>
     </el-card>
 
-    <dialog-form
-      v-model="dialogVisible"
-      :dialogConfig="dialogConfig"
-      :formConfig="formConfig"
-      :formData="formData"
-      :create="crud.create"
-      :update="crud.update"
-      @success="handleFormSuccess"
-      v-if="dialogVisible"
-    />
+    <template v-if="formMode === 'dialog'">
+      <dialog-form
+        v-model="formVisible"
+        v-if="formVisible"
+        :dialogConfig="dialogConfig"
+        :formConfig="formConfig"
+        :formData="formData"
+        :formSlots="formSlots"
+        :create="crud.create"
+        :update="crud.update"
+        @success="handleFormSuccess"
+      >
+        <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
+          <slot :name="slot.alias" v-bind="slotProps"></slot>
+        </template>
+      </dialog-form>
+    </template>
+    <template v-else>
+      <drawer-form
+        v-model="formVisible"
+        v-if="formVisible"
+        :drawerConfig="drawerConfig"
+        :formConfig="formConfig"
+        :formData="formData"
+        :formSlots="formSlots"
+        :create="crud.create"
+        :update="crud.update"
+        @success="handleFormSuccess"
+      >
+        <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
+          <slot :name="slot.alias" v-bind="slotProps"></slot>
+        </template>
+      </drawer-form>
+    </template>
   </div>
 </template>
 

+ 3 - 8
src/components/core/ProTable.vue

@@ -7,7 +7,7 @@ import { useForm } from '@/hooks/useForm'
 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 { BasicForm, ICRUD } from '@/types/form'
 import type { VxeToolbarProps } from 'vxe-table'
 
 interface CustomTable {
@@ -61,7 +61,8 @@ const {
   handleDelete,
   handleBatchDelete,
   handleUpdate,
-  handleView
+  handleView,
+  handleFormSuccess
 } = useTable(props, emits)
 
 const tableConfig = computed<CustomTable>(() => ({
@@ -110,14 +111,8 @@ watch(
 )
 // ============== 表格部分结束 ===============
 
-// ============== 表单部分开始 ===============
-const handleFormSuccess = () => {
-  getTableData()
-}
-
 // 构造表单插槽
 const { formSlots } = useForm(props)
-// ============== 表单部分结束 ===============
 
 defineExpose({
   handleCreate,

+ 6 - 1
src/hooks/useTable.ts

@@ -142,6 +142,10 @@ export const useTable = (props: any, emits: any) => {
   }
   // ============== crud部分结束 ===============
 
+  const handleFormSuccess = () => {
+    getTableData()
+  }
+
   return {
     tableData,
     total,
@@ -156,6 +160,7 @@ export const useTable = (props: any, emits: any) => {
     handleDelete,
     handleBatchDelete,
     handleUpdate,
-    handleView
+    handleView,
+    handleFormSuccess
   }
 }