tongshangming 2 лет назад
Родитель
Сommit
1715923235

+ 0 - 2
src/components/GlobalTabs.vue

@@ -1,7 +1,6 @@
 <script lang="ts" setup>
 import type { TabPaneName } from 'element-plus'
 import config from '@/config/defaultSetting'
-import { useThemeStore } from '@/stores/theme'
 import { useMenuStore } from '@/stores/menu'
 
 interface Tab {
@@ -47,7 +46,6 @@ const setTab = (tab: Tab) => {
   }
   tabs.value.push(tab)
 }
-const themeStore = useThemeStore()
 const menuStore = useMenuStore()
 const activeMenu = ref({})
 const findActiveMenu = (path: any) => {

+ 20 - 3
src/components/ProTable.vue

@@ -7,7 +7,7 @@ export default {
 <script setup lang="ts">
 import router from '@/router'
 import { ElMessage, ElMessageBox, type DialogProps } from 'element-plus'
-import type { AdvancedForm, BasicForm, ICRUD } from '@/types/form'
+import type { AdvancedForm, BasicForm, ICRUD, formSlot } from '@/types/form'
 import type { VXEComponent, VxeToolbarProps, VxeToolbarEventProps } from 'vxe-table'
 
 interface CustomTable {
@@ -194,6 +194,15 @@ const dialogVisible = ref(false)
 const handleFormSuccess = () => {
   getTableData()
 }
+
+const formSlots = ref<formSlot[]>([])
+if (props.formConfig.advanced) {
+  props.formConfig.formItems.forEach((item: any) => {
+    item.group.forEach((subItem: any) => Array.prototype.push.apply(formSlots.value, subItem.slots))
+  })
+} else {
+  props.formConfig.formItems.forEach((item: any) => Array.prototype.push.apply(formSlots.value, item.slots))
+}
 // ============== 表单部分结束 ===============
 
 defineExpose({
@@ -209,7 +218,11 @@ defineExpose({
     <el-card class="mb-4" shadow="never" v-if="searchList.length || slots.query">
       <el-form :inline="true">
         <el-form-item :label="item.label" v-for="(item, index) in searchList" :key="index">
-          <form-comp :item="item" v-model="query[item.name]"></form-comp>
+          <form-comp :item="item" v-model="query[item.name]">
+            <template #[slot.alias] v-for="slot in item.slots" :key="slot.alias">
+              <slot :name="slot.alias"></slot>
+            </template>
+          </form-comp>
         </el-form-item>
         <slot name="query" :query="query"></slot>
         <el-form-item>
@@ -288,7 +301,11 @@ defineExpose({
       :update="crud.update"
       @success="handleFormSuccess"
       v-if="dialogVisible"
-    />
+    >
+      <template #[slot.alias] v-for="slot in formSlots" :key="slot.alias">
+        <slot :name="slot.alias"></slot>
+      </template>
+    </dialog-form>
   </div>
 </template>
 

+ 5 - 1
src/components/form/BasicForm.vue

@@ -24,7 +24,11 @@ const formData = computed(() => {
   <el-row :gutter="20">
     <el-col :span="item.span || formConfig.span || 12" v-for="(item, index) in formConfig.formItems" :key="index">
       <el-form-item :label="item.label" :rules="item.rules" :prop="item.name">
-        <form-comp :item="item" v-model="formData[item.name]"></form-comp>
+        <form-comp :item="item" v-model="formData[item.name]">
+          <template #[slot.alias] v-for="slot in item.slots" :key="slot.alias">
+            <slot :name="slot.alias"></slot>
+          </template>
+        </form-comp>
       </el-form-item>
     </el-col>
   </el-row>

+ 15 - 2
src/components/form/DialogForm.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { BasicForm, AdvancedForm } from '@/types/form'
+import type { BasicForm, AdvancedForm, formSlot } from '@/types/form'
 import type { DialogProps } from 'element-plus'
 
 interface Props {
@@ -21,6 +21,15 @@ watchEffect(() => {
 
 const formRef = ref()
 
+const formSlots = ref<formSlot[]>([])
+if (props.formConfig.advanced) {
+  props.formConfig.formItems.forEach((item: any) => {
+    item.group.forEach((subItem: any) => Array.prototype.push.apply(formSlots.value, subItem.slots))
+  })
+} else {
+  props.formConfig.formItems.forEach((item: any) => Array.prototype.push.apply(formSlots.value, item.slots))
+}
+
 const dialogTitle = computed(() => (props.formData.id ? '编辑' : '新增'))
 const dialogVisible = computed({
   get: () => props.modelValue,
@@ -50,7 +59,11 @@ const submit = async () => {
     @close="closeDialog"
     :close-on-click-modal="false"
   >
-    <pro-form ref="formRef" :formConfig="formConfig" :formData="formInitData" :create="create" :update="update" />
+    <pro-form ref="formRef" :formConfig="formConfig" :formData="formInitData" :create="create" :update="update">
+      <template #[slot.alias] v-for="slot in formSlots" :key="slot.alias">
+        <slot :name="slot.alias"></slot>
+      </template>
+    </pro-form>
 
     <template #footer>
       <el-button icon="Close" @click="closeDialog">取消</el-button>

+ 19 - 2
src/components/form/FormComp.vue

@@ -51,7 +51,11 @@ const handleUploadSuccess: UploadProps['onSuccess'] = response => {
     v-bind="item.props"
     v-on="item.events || {}"
     :placeholder="item.placeholder || placeholder(item)"
-  />
+  >
+    <template #[slot.name]="{ node, data }" v-for="slot in item.slots" :key="slot.alias">
+      <slot :name="slot.alias" :node="node" :data="data"></slot>
+    </template>
+  </el-cascader>
   <el-date-picker
     v-else-if="item.type === 'date-picker'"
     style="width: 100%"
@@ -59,7 +63,11 @@ const handleUploadSuccess: UploadProps['onSuccess'] = response => {
     v-bind="item.props"
     v-on="item.events || {}"
     :placeholder="item.placeholder || placeholder(item)"
-  />
+  >
+    <template #[slot.name] v-for="slot in item.slots" :key="slot.alias">
+      <slot :name="slot.alias"></slot>
+    </template>
+  </el-date-picker>
   <el-upload
     v-else-if="item.type === 'upload'"
     :on-success="handleUploadSuccess"
@@ -70,6 +78,9 @@ const handleUploadSuccess: UploadProps['onSuccess'] = response => {
   >
     <img v-if="modelValue" :src="modelValue" class="avatar" />
     <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+    <template #[slot.name] v-for="slot in item.slots" :key="slot.alias">
+      <slot :name="slot.alias"></slot>
+    </template>
   </el-upload>
   <el-select
     v-else-if="item.type === 'select'"
@@ -85,6 +96,9 @@ const handleUploadSuccess: UploadProps['onSuccess'] = response => {
       :key="index"
       v-bind="option.props"
     ></el-option>
+    <template #[slot.name] v-for="slot in item.slots" :key="slot.alias">
+      <slot :name="slot.alias"></slot>
+    </template>
   </el-select>
   <component
     v-else
@@ -104,6 +118,9 @@ const handleUploadSuccess: UploadProps['onSuccess'] = response => {
         {{ option.value }}
       </el-checkbox>
     </template>
+    <template #[slot.name] v-for="slot in item.slots" :key="slot.alias">
+      <slot :name="slot.alias"></slot>
+    </template>
   </component>
 </template>
 

+ 15 - 2
src/components/form/ProForm.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import type { BasicForm, AdvancedForm } from '@/types/form'
+import type { BasicForm, AdvancedForm, formSlot } from '@/types/form'
 import { ElMessage } from 'element-plus'
 
 interface Props {
@@ -23,6 +23,15 @@ const formInitData = computed(() => {
 })
 const formRef = ref()
 
+const formSlots = ref<formSlot[]>([])
+if (props.formConfig.advanced) {
+  props.formConfig.formItems.forEach((item: any) => {
+    item.group.forEach((subItem: any) => Array.prototype.push.apply(formSlots.value, subItem.slots))
+  })
+} else {
+  props.formConfig.formItems.forEach((item: any) => Array.prototype.push.apply(formSlots.value, item.slots))
+}
+
 const submit = async () => {
   let message
   return formRef.value.validate().then(async () => {
@@ -54,7 +63,11 @@ defineExpose({
 <template>
   <el-form :model="formInitData" ref="formRef" v-bind="formProps" class="form">
     <advanced-form :formConfig="formConfig" :formData="formInitData" v-if="formConfig.advanced" />
-    <basic-form :formConfig="formConfig" :formData="formInitData" v-else />
+    <basic-form :formConfig="formConfig" :formData="formInitData" v-else>
+      <template #[slot.alias] v-for="slot in formSlots" :key="slot.alias">
+        <slot :name="slot.alias"></slot>
+      </template>
+    </basic-form>
   </el-form>
 </template>
 

+ 6 - 0
src/types/form.ts

@@ -1,5 +1,10 @@
 import type { FormProps, FormItemRule } from 'element-plus'
 
+export type formSlot = {
+  name: string
+  alias: string
+}
+
 export type BasicFormItem = {
   label: string
   value: any
@@ -15,6 +20,7 @@ export type BasicFormItem = {
   props?: object
   events?: object
   request?: Function
+  slots?: Array<formSlot>
 }
 
 export type AdvancedFormItem = {

+ 28 - 9
src/views/form/Basic.vue

@@ -47,13 +47,33 @@ const formConfig = reactive<BasicForm>({
       label: '字段名',
       value: '',
       name: 'name',
-      type: 'input'
+      type: 'input',
+      slots: [
+        {
+          name: 'prepend',
+          alias: 'prepend1'
+        },
+        {
+          name: 'append',
+          alias: 'append1'
+        }
+      ]
     },
     {
       label: '字段名',
       value: '',
       name: 'name',
-      type: 'input'
+      type: 'input',
+      slots: [
+        {
+          name: 'prepend',
+          alias: 'prepend'
+        },
+        {
+          name: 'append',
+          alias: 'append'
+        }
+      ]
     }
   ]
 })
@@ -76,13 +96,12 @@ const handleSave = () => {
 <template>
   <div class="h-full bg-white p-16px pt-50px flex justify-center">
     <div class="w-500px">
-      <pro-form
-        :formConfig="formConfig"
-        :formData="formData"
-        :create="create"
-        :update="update"
-        ref="proFormRef"
-      ></pro-form>
+      <pro-form :formConfig="formConfig" :formData="formData" :create="create" :update="update" ref="proFormRef">
+        <template #prepend> testt </template>
+        <template #prepend1> test1 </template>
+        <template #append> testt </template>
+        <template #append1> test1 </template>
+      </pro-form>
       <div class="text-center">
         <el-button type="primary" @click="handleSave">保存</el-button>
       </div>