Browse Source

新增DrawerForm组件

tongshangming 1 year ago
parent
commit
dd83b6c2bb

+ 1 - 0
src/components.d.ts

@@ -18,6 +18,7 @@ declare module 'vue' {
     DesignerRender: typeof import('./components/designer/DesignerRender.vue')['default']
     DesignerSetting: typeof import('./components/designer/DesignerSetting.vue')['default']
     DialogForm: typeof import('./components/core/form/DialogForm.vue')['default']
+    DrawerForm: typeof import('./components/core/form/DrawerForm.vue')['default']
     DynamicFormEdit: typeof import('./components/DynamicFormEdit.vue')['default']
     ElArea: typeof import('./components/form/ElArea.vue')['default']
     ElCustom: typeof import('./components/form/ElCustom.vue')['default']

+ 51 - 25
src/components/core/ProTable.vue

@@ -6,9 +6,10 @@ export default {
 
 <script setup lang="ts">
 import router from '@/router'
-import { ElMessage, ElMessageBox, type DialogProps } from 'element-plus'
+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 } from 'vxe-table'
+import type { VXEComponent, VxeToolbarProps, VxeToolbarEventProps, VxeToolbarPropTypes } from 'vxe-table'
 import { buildFormSlots } from '@/utils/utils'
 
 interface CustomTable {
@@ -24,17 +25,20 @@ interface Props {
   pageSize?: number
   selection?: boolean
   formConfig: BasicForm
-  dialogConfig?: DialogProps
+  dialogConfig?: Partial<DialogProps>
+  drawerConfig?: Partial<DrawerProps>
   tableConfig?: CustomTable
-  toolbarConfig?: VXEComponent<VxeToolbarProps, VxeToolbarEventProps>
+  toolbarConfig?: VxeToolbarProps
   showToolbar?: boolean
   height?: string
+  formMode?: 'dialog' | 'drawer'
 }
 
 const props = withDefaults(defineProps<Props>(), {
   pageSize: 10,
   selection: true,
-  showToolbar: true
+  showToolbar: true,
+  formMode: 'dialog'
 })
 
 const emits = defineEmits(['click-create', 'click-edit', 'click-view', 'click-reset', 'checkbox-change'])
@@ -150,7 +154,7 @@ const handleCreate = () => {
   } else {
     formData.value = {}
     props.formConfig.disabled = false
-    dialogVisible.value = true
+    formVisible.value = true
   }
 }
 const handleUpdate = (row: any) => {
@@ -166,7 +170,7 @@ const handleUpdate = (row: any) => {
       formData.value = { ...row }
     }
     props.formConfig.disabled = false
-    dialogVisible.value = true
+    formVisible.value = true
   }
 }
 const handleView = (row: any) => {
@@ -182,7 +186,7 @@ const handleView = (row: any) => {
       formData.value = { ...row }
     }
     props.formConfig.disabled = true
-    dialogVisible.value = true
+    formVisible.value = true
   }
 }
 const handleDelete = (id: string | number) => {
@@ -230,7 +234,7 @@ const handleBatchDelete = () => {
 
 // ============== 表单部分开始 ===============
 const formData = ref<any>({})
-const dialogVisible = ref(false)
+const formVisible = ref(false)
 const handleFormSuccess = () => {
   getTableData()
 }
@@ -245,8 +249,11 @@ defineExpose({
   handleDelete,
   handleUpdate,
   handleView,
+  handleQuery,
+  handleReset,
   refresh,
-  formData
+  formData,
+  query
 })
 </script>
 
@@ -332,21 +339,40 @@ defineExpose({
       </div>
     </el-card>
 
-    <dialog-form
-      v-model="dialogVisible"
-      v-if="dialogVisible"
-      :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 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>
 

+ 1 - 1
src/components/core/form/DialogForm.vue

@@ -5,7 +5,7 @@ import { buildFormSlots } from '@/utils/utils'
 
 interface Props {
   modelValue: boolean
-  dialogConfig?: DialogProps
+  dialogConfig?: Partial<DialogProps>
   formSlots?: Array<FormSlot>
   formConfig: BasicForm
   formData: any

+ 89 - 0
src/components/core/form/DrawerForm.vue

@@ -0,0 +1,89 @@
+<script setup lang="ts">
+import type { BasicForm, FormSlot } from '@/types/form'
+import type { DrawerProps } from 'element-plus'
+import { buildFormSlots } from '@/utils/utils'
+
+interface Props {
+  modelValue: boolean
+  drawerConfig?: Partial<DrawerProps>
+  formSlots?: Array<FormSlot>
+  formConfig: BasicForm
+  formData: any
+  create: Function
+  update: Function
+}
+
+const props = defineProps<Props>()
+const emits = defineEmits(['update:modelValue', 'success'])
+
+const formInitData = ref({})
+watchEffect(() => {
+  formInitData.value = props.formData
+})
+
+const formRef = ref()
+
+// 构造表单插槽
+const formSlots = ref<FormSlot[]>(props.formSlots || [])
+if (!props.formSlots) {
+  buildFormSlots(props.formConfig.formItems, formSlots.value)
+}
+
+const title = computed(() => {
+  if (props.formConfig.disabled) {
+    return '查看'
+  } else {
+    return props.formData.id ? '编辑' : '新增'
+  }
+})
+const drawerVisible = computed({
+  get: () => props.modelValue,
+  set: value => emits('update:modelValue', value)
+})
+
+const closeDrawer = () => {
+  drawerVisible.value = false
+  formInitData.value = {}
+}
+
+const submit = async () => {
+  const res = await formRef.value.submit()
+  if (res) {
+    closeDrawer()
+    emits('success')
+  }
+}
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      :title="title"
+      v-bind="drawerConfig"
+      v-model="drawerVisible"
+      @close="closeDrawer"
+      :close-on-click-modal="false"
+    >
+      <pro-form
+        class="pro-form"
+        ref="formRef"
+        :formConfig="formConfig"
+        :formData="formInitData"
+        :formSlots="formSlots"
+        :create="create"
+        :update="update"
+      >
+        <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
+          <slot :name="slot.alias" v-bind="slotProps"></slot>
+        </template>
+      </pro-form>
+
+      <template #footer v-if="!formConfig.disabled">
+        <el-button icon="Close" @click="closeDrawer">取消</el-button>
+        <el-button icon="Check" type="primary" @click="submit">保存</el-button>
+      </template>
+    </el-drawer>
+  </div>
+</template>
+
+<style lang="scss" scoped></style>

+ 1 - 5
src/views/system/menu.vue

@@ -322,11 +322,7 @@ const rowClassName = ({ row }: { row: any }) => {
       </el-card>
     </template>
     <template #right>
-      <el-empty
-        v-if="menuId == ''"
-        description="请选择左侧菜单后操作"
-        image="http://cloud.jeeplus.org/assets/empty.066d9fc7.svg"
-      />
+      <el-empty v-if="menuId == ''" description="请选择左侧菜单后操作" />
       <PaneModel v-else :config="configSmall" class="form-scoll">
         <template #left>
           <el-card class="right">