ProForm.vue 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. <script setup lang="ts">
  2. import type { BasicForm, AdvancedForm, formSlot } from '@/types/form'
  3. import { ElMessage } from 'element-plus'
  4. interface Props {
  5. formConfig: BasicForm | AdvancedForm
  6. formData: any
  7. create: Function
  8. update: Function
  9. }
  10. const props = defineProps<Props>()
  11. const formProps: any = ref({
  12. labelWidth: '100px',
  13. labelPosition: 'top',
  14. size: 'large',
  15. ...props.formConfig?.props
  16. })
  17. const formInitData = computed(() => {
  18. return props.formData
  19. })
  20. const formRef = ref()
  21. // 构造表单插槽
  22. const formSlots = ref<formSlot[]>([])
  23. if (props.formConfig.advanced) {
  24. props.formConfig.formItems.forEach((item: any) => {
  25. item.group.forEach((subItem: any) => Array.prototype.push.apply(formSlots.value, subItem.slots))
  26. })
  27. } else {
  28. props.formConfig.formItems.forEach((item: any) => Array.prototype.push.apply(formSlots.value, item.slots))
  29. }
  30. const submit = async () => {
  31. let message
  32. return formRef.value.validate().then(async () => {
  33. try {
  34. if (formInitData.value.id) {
  35. await props.update(formInitData.value)
  36. message = '编辑成功'
  37. } else {
  38. await props.create(formInitData.value)
  39. message = '新增成功'
  40. }
  41. ElMessage({
  42. type: 'success',
  43. message
  44. })
  45. return true
  46. } catch (error) {
  47. return false
  48. }
  49. })
  50. }
  51. defineExpose({
  52. submit
  53. })
  54. </script>
  55. <template>
  56. <el-form :model="formInitData" ref="formRef" v-bind="formProps" class="form">
  57. <advanced-form :formConfig="formConfig" :formData="formInitData" v-if="formConfig.advanced">
  58. <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
  59. <slot :name="slot.alias" v-bind="slotProps"></slot>
  60. </template>
  61. </advanced-form>
  62. <basic-form :formConfig="formConfig" :formData="formInitData" v-else>
  63. <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
  64. <slot :name="slot.alias" v-bind="slotProps"></slot>
  65. </template>
  66. </basic-form>
  67. </el-form>
  68. </template>
  69. <style lang="scss" scoped>
  70. :deep(.el-select) {
  71. width: 100%;
  72. }
  73. </style>