浏览代码

feat: 自定义表单基本完成,剩下默认值没解决

huangziyang 1 月之前
父节点
当前提交
399a99da25

二进制
form/favicon.ico


+ 0 - 44
form/index.html

@@ -1,44 +0,0 @@
-<!DOCTYPE html><html lang=""><head>
-    <meta charset="UTF-8">
-    <link rel="icon" href="/saas/form/favicon.ico">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Vite App</title>
-    <script crossorigin="">import('/saas/form/static/index.DLXmMD_z.js').finally(() => {
-            
-    const qiankunLifeCycle = window.moudleQiankunAppLifeCycles && window.moudleQiankunAppLifeCycles['curstom-form'];
-    if (qiankunLifeCycle) {
-      window.proxy.vitemount((props) => qiankunLifeCycle.mount(props));
-      window.proxy.viteunmount((props) => qiankunLifeCycle.unmount(props));
-      window.proxy.vitebootstrap(() => qiankunLifeCycle.bootstrap());
-      window.proxy.viteupdate((props) => qiankunLifeCycle.update(props));
-    }
-  
-          })</script>
-    <link rel="stylesheet" crossorigin="" href="/saas/form/static/index.ztoF2Rpi.css">
-  </head>
-  <body>
-    <div id="app"></div>
-  
-
-<script>
-  const createDeffer = (hookName) => {
-    const d = new Promise((resolve, reject) => {
-      window.proxy && (window.proxy[`vite${hookName}`] = resolve)
-    })
-    return props => d.then(fn => fn(props));
-  }
-  const bootstrap = createDeffer('bootstrap');
-  const mount = createDeffer('mount');
-  const unmount = createDeffer('unmount');
-  const update = createDeffer('update');
-
-  ;(global => {
-    global.qiankunName = 'curstom-form';
-    global['curstom-form'] = {
-      bootstrap,
-      mount,
-      unmount,
-      update
-    };
-  })(window);
-</script></body></html>

文件差异内容过多而无法显示
+ 0 - 0
form/static/index.DLXmMD_z.js


文件差异内容过多而无法显示
+ 0 - 0
form/static/index.ztoF2Rpi.css


+ 0 - 19
patches/@form-create__designer.patch

@@ -1,19 +0,0 @@
-diff --git a/src/components/FcDesigner.vue b/src/components/FcDesigner.vue
-index 80befe737bd814492e65ca885f9b1d3cc96de28d..c94b142dc69ba31862d4cc398218d8c70eeb2bcc 100644
---- a/src/components/FcDesigner.vue
-+++ b/src/components/FcDesigner.vue
-@@ -992,6 +992,14 @@ export default defineComponent({
-                     {language: 'xml'}
-                 ).value
-             },
-+            closePreview() {
-+                data.preview = {
-+                    state: false,
-+                    rule: [],
-+                    option: {},
-+                    api: {},
-+                };
-+            },
-             copyCode() {
-                 copyTextToClipboard(this.$refs.previewCode.innerText);
-             },

文件差异内容过多而无法显示
+ 571 - 212
pnpm-lock.yaml


+ 0 - 2
pnpm-workspace.yaml

@@ -1,2 +0,0 @@
-patchedDependencies:
-  '@form-create/designer': patches/@form-create__designer.patch

+ 36 - 20
src/App.vue

@@ -1,17 +1,19 @@
 <!-- eslint-disable @typescript-eslint/no-explicit-any -->
 <!-- eslint-disable @typescript-eslint/no-explicit-any -->
-<!-- eslint-disable @typescript-eslint/ban-ts-comment -->
 <script setup lang="ts">
 <script setup lang="ts">
-import { ref, onMounted, nextTick } from 'vue'
-import { qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
+import { ref, onMounted } from 'vue'
 import type { Config, Handle } from '@form-create/designer'
 import type { Config, Handle } from '@form-create/designer'
-// import { formCreate } from '@form-create/designer'
 import { formConfig } from './form.config.ts'
 import { formConfig } from './form.config.ts'
 import FcDesigner from '@form-create/designer'
 import FcDesigner from '@form-create/designer'
+// 组件
 import { RcSelect } from './plugins/components/rc-select.config.ts'
 import { RcSelect } from './plugins/components/rc-select.config.ts'
 import { RcRadio } from './plugins/components/rc-radio.config.ts'
 import { RcRadio } from './plugins/components/rc-radio.config.ts'
+import { RcCheckbox } from './plugins/components/rc-checkbox.config.ts'
+// 菜单
 import { MenuOptions } from './plugins/menu/options.ts'
 import { MenuOptions } from './plugins/menu/options.ts'
+import { MenuUpload } from './plugins/menu/upload.ts'
+
 import type { FcDesignerInstance } from '@form-create/designer' // 注册组件
 import type { FcDesignerInstance } from '@form-create/designer' // 注册组件
-import { RcCheckbox } from './plugins/components/rc-checkbox.ts'
+import { RcUpload } from './plugins/components/rc-upload.config.ts'
 
 
 /**
 /**
  * @see https://view.form-create.com/methods
  * @see https://view.form-create.com/methods
@@ -20,11 +22,12 @@ declare global {
   interface Window {
   interface Window {
     __QIANKUN__EVENT__: {
     __QIANKUN__EVENT__: {
       on: (name: string, fn: (...arg: any[]) => void) => void
       on: (name: string, fn: (...arg: any[]) => void) => void
-      emit: (name: string, ...arg: any[]) => void
+      emit: (name: string, ...arg: any[]) => boolean
     } // 事件中心
     } // 事件中心
-    __QIANKUN__REQUSET__: () => void // 请求API接口
+    __QIANKUN__REQUSET__: any // 请求API接口
     __QIANKUN__GUID__: () => string // 获取唯一标识
     __QIANKUN__GUID__: () => string // 获取唯一标识
     __QIANKUN__OPEN__TAG__: () => void // 打开标签页
     __QIANKUN__OPEN__TAG__: () => void // 打开标签页
+    __QIANKUN__QUITE__: () => void // 返回页面
   }
   }
 }
 }
 // 表单实例
 // 表单实例
@@ -32,33 +35,41 @@ const designer = ref<FcDesignerInstance | null>(null)
 const api = ref(null)
 const api = ref(null)
 // 表单模板元素
 // 表单模板元素
 // 判断是独立运行的还是qiankun子应用
 // 判断是独立运行的还是qiankun子应用
-const height = ref(qiankunWindow.__POWERED_BY_QIANKUN__ ? '90vh' : '100vh')
+const height = ref('100vh')
 const config = ref<Config>(formConfig)
 const config = ref<Config>(formConfig)
 // 顶部更多操作按钮
 // 顶部更多操作按钮
 const handle = ref<Handle>([])
 const handle = ref<Handle>([])
 // console.log('子应用', window.__QIANKUN__EVENT__)
 // console.log('子应用', window.__QIANKUN__EVENT__)
 
 
-const onSave = (config: { options: string; rule: string }) => {
+const onSave = async (config: { options: string; rule: string }) => {
   const rule = config.rule
   const rule = config.rule
-  console.log(rule)
+  const options = config.options
+  // 接收从主应用过来的事件
+  window.__QIANKUN__EVENT__?.emit('save', {
+    rule: JSON.parse(rule),
+    options: JSON.parse(options),
+    original: config,
+  })
 }
 }
 
 
-onMounted(() => {
-  designer.value?.openPreview()
-  nextTick(() => {
-    // @ts-ignore
-    designer.value!.preview.state = false
-  })
-})
+const rule = ref(
+  '[{"type":"rc-checkbox","title":"多选框","props":{"clearable":true,"options":[{"key":"cw_1iqkm6k0p1n4111p61q8g8katdn1","label":"1234","value":"1234","validate":false,"tags":[]}]},"_fc_id":"id_Fd0jmadjp53oaec","name":"ref_Fw5smadjp53oafc","field":"Fnqymadjp53oagc","display":true,"hidden":false,"_fc_drag_tag":"rc-checkbox","options":[{"key":"cw_1iqkm6k0p1n4111p61q8g8katdn1","label":"1234","value":"1234","validate":false,"tags":[]}]},{"type":"rc-radio","title":"单选框","props":{"clearable":true,"options":[{"key":"cw_1iqkm6nli1v4f8p01pn01rs715r62","label":"1234","value":"1234","validate":false,"tags":[]}]},"_fc_id":"id_Fo8imadjp7v1ahc","name":"ref_F6j0madjp7v1aic","field":"Fhyhmadjp7v1ajc","display":true,"hidden":false,"_fc_drag_tag":"rc-radio","options":[{"key":"cw_1iqkm6nli1v4f8p01pn01rs715r62","label":"1234","value":"1234","validate":false,"tags":[]}]},{"type":"rc-upload","title":"图片","props":{"clearable":true},"_fc_id":"id_Fyhlmadknfeuabc","name":"ref_Fz6bmadknfeuacc","field":"Fj86madknfeuadc","display":true,"hidden":false,"_fc_drag_tag":"rc-upload"}]',
+)
 
 
-onMounted(() => {
+onMounted(async () => {
   // 注册拖拽规则
   // 注册拖拽规则
+  designer.value?.addMenu(MenuOptions)
+  designer.value?.addMenu(MenuUpload)
   designer.value?.addComponent(RcSelect)
   designer.value?.addComponent(RcSelect)
   designer.value?.addComponent(RcRadio)
   designer.value?.addComponent(RcRadio)
   designer.value?.addComponent(RcCheckbox)
   designer.value?.addComponent(RcCheckbox)
+  designer.value?.addComponent(RcUpload)
 
 
   // 注册菜单
   // 注册菜单
-  designer.value?.addMenu(MenuOptions)
+  console.log(designer.value)
+
+  // 设置拖拽规则
+  designer.value?.setRule(rule.value)
 })
 })
 </script>
 </script>
 
 
@@ -68,7 +79,12 @@ onMounted(() => {
     :height="height"
     :height="height"
     :handle="handle"
     :handle="handle"
     :config="config"
     :config="config"
-    @save="onSave"
     v-model:api="api"
     v-model:api="api"
+    @save="onSave"
+    @inputDate="
+      () => {
+        console.log(12313213)
+      }
+    "
   />
   />
 </template>
 </template>

+ 16 - 10
src/components/index.ts

@@ -1,12 +1,18 @@
-import formCreate from '@form-create/element-ui'
-import RcOptions from './rc-options/rc-options.vue'
-import RcSelect from './rc-select/rc-select.vue'
-import RcRadio from './rc-radio/rc-radio.vue'
-import RcCheckbox from './rc-checkbox/rc-checkbox.vue'
-const setupComponent = () => {
-  formCreate.component(RcOptions.__name!, RcOptions)
-  formCreate.component(RcSelect.__name!, RcSelect)
-  formCreate.component(RcRadio.__name!, RcRadio)
-  formCreate.component(RcRadio.__name!, RcCheckbox)
+import type { App, Component } from 'vue'
+const setupComponent = async (app: App) => {
+  const components = import.meta.glob<
+    Component & {
+      __name: string
+    }
+  >('./**/*.vue', {
+    import: 'default',
+    eager: true,
+  })
+  for (const path in components) {
+    app.component(
+      components[path as keyof typeof components].__name!,
+      components[path as keyof typeof components],
+    )
+  }
 }
 }
 export default setupComponent
 export default setupComponent

+ 1 - 1
src/components/rc-checkbox/rc-checkbox.vue

@@ -1,6 +1,6 @@
 <script lang="ts" name="rc-checkbox" setup>
 <script lang="ts" name="rc-checkbox" setup>
 import type { FormCreateProps } from '@form-create/element-ui'
 import type { FormCreateProps } from '@form-create/element-ui'
-import RcCreateOption from '../rc-options/rc-create-option.vue'
+import RcCreateOption from '../rc-options/create-option.vue'
 import { ref } from 'vue'
 import { ref } from 'vue'
 
 
 defineProps<{
 defineProps<{

+ 2 - 1
src/components/rc-options/rc-create-option.vue → src/components/rc-options/create-option.vue

@@ -1,6 +1,6 @@
 <script lang="ts" name="rc-select" setup>
 <script lang="ts" name="rc-select" setup>
 import type { FormCreateProps } from '@form-create/element-ui'
 import type { FormCreateProps } from '@form-create/element-ui'
-import type { Option } from '../rc-options/createOptions.ts'
+import type { Option } from './createOptions.ts'
 import { onMounted, ref } from 'vue'
 import { onMounted, ref } from 'vue'
 const props = defineProps<{
 const props = defineProps<{
   formCreateInject: FormCreateProps & {
   formCreateInject: FormCreateProps & {
@@ -10,6 +10,7 @@ const props = defineProps<{
 
 
 const options = ref<Option[]>([])
 const options = ref<Option[]>([])
 
 
+// 注册组件的事件, 获取右边标签改变时的值
 window.__QIANKUN__EVENT__?.on(props.formCreateInject.field, (tags: Option[]) => {
 window.__QIANKUN__EVENT__?.on(props.formCreateInject.field, (tags: Option[]) => {
   if (props.formCreateInject.rule?.props === void 0) {
   if (props.formCreateInject.rule?.props === void 0) {
     return
     return

+ 2 - 0
src/components/rc-options/createOptions.ts

@@ -2,6 +2,8 @@ export interface Option {
   key: string
   key: string
   label: string
   label: string
   value: string
   value: string
+  validate: boolean
+  default: string
   tags?: {
   tags?: {
     corpid: string
     corpid: string
     group_id: string
     group_id: string

+ 39 - 5
src/components/rc-options/rc-options.vue

@@ -1,9 +1,9 @@
 <script lang="ts" name="rc-options" setup>
 <script lang="ts" name="rc-options" setup>
-import { onUpdated, ref } from 'vue'
+import { nextTick, onMounted, onUpdated, ref } from 'vue'
 import { Delete, Plus } from '@element-plus/icons-vue'
 import { Delete, Plus } from '@element-plus/icons-vue'
 import { type Option } from './createOptions'
 import { type Option } from './createOptions'
 import { debounce } from '@/utils/debouce'
 import { debounce } from '@/utils/debouce'
-import type { FormCreateProps } from '@form-create/element-ui'
+import type { FormCreateProps, Rule } from '@form-create/element-ui'
 
 
 // 传递弹窗过来的数据
 // 传递弹窗过来的数据
 window.__QIANKUN__EVENT__?.on('tagsChange', (tags: Option['tags']) => {
 window.__QIANKUN__EVENT__?.on('tagsChange', (tags: Option['tags']) => {
@@ -12,12 +12,15 @@ window.__QIANKUN__EVENT__?.on('tagsChange', (tags: Option['tags']) => {
 let currentIndex = 0
 let currentIndex = 0
 const getId = window.__QIANKUN__GUID__ || (() => 'default-guid')
 const getId = window.__QIANKUN__GUID__ || (() => 'default-guid')
 
 
-const optionList = ref<Option[]>([])
-
 const props = defineProps<{
 const props = defineProps<{
-  formCreateInject: FormCreateProps
+  formCreateInject: Omit<FormCreateProps, 'api'> & {
+    api: {
+      activeRule: Rule
+    }
+  }
   field: string
   field: string
 }>()
 }>()
+const optionList = ref<Option[]>([])
 
 
 // 新增选项
 // 新增选项
 const onAddClick = () => {
 const onAddClick = () => {
@@ -25,7 +28,9 @@ const onAddClick = () => {
     key: getId(),
     key: getId(),
     label: '',
     label: '',
     value: '',
     value: '',
+    validate: false,
     tags: [],
     tags: [],
+    default: '',
   })
   })
 }
 }
 
 
@@ -40,6 +45,24 @@ const onOpenTagsDialog = (index: number) => {
   window.__QIANKUN__OPEN__TAG__?.()
   window.__QIANKUN__OPEN__TAG__?.()
 }
 }
 
 
+const validate = (value: string, currentItem: Option) => {
+  if (value === '') {
+    optionList.value.forEach((item) => {
+      item.validate = false
+    })
+    return
+  }
+  // 将所有设置一次
+  optionList.value.forEach((item) => {
+    item.validate = item.label === value
+  })
+  const validateNum = optionList.value.filter((item) => item.validate).length
+  if (validateNum > 1) {
+    return
+  }
+  currentItem.validate = false
+}
+
 onUpdated(
 onUpdated(
   debounce(() => {
   debounce(() => {
     window.__QIANKUN__EVENT__?.emit(
     window.__QIANKUN__EVENT__?.emit(
@@ -48,6 +71,15 @@ onUpdated(
     )
     )
   }),
   }),
 )
 )
+
+onMounted(() => {
+  nextTick(() => {
+    if (props.formCreateInject?.api?.activeRule?.options === void 0) {
+      return
+    }
+    optionList.value = props.formCreateInject.api.activeRule.options as Option[]
+  })
+})
 </script>
 </script>
 <template>
 <template>
   <div class="options-container">
   <div class="options-container">
@@ -64,9 +96,11 @@ onUpdated(
             autosize
             autosize
             type="textarea"
             type="textarea"
             placeholder="请输入内容"
             placeholder="请输入内容"
+            @change="(e: string) => validate(e, item)"
           />
           />
           <el-icon style="cursor: pointer" @click="onRemoveClick(index)"><Delete /></el-icon>
           <el-icon style="cursor: pointer" @click="onRemoveClick(index)"><Delete /></el-icon>
         </div>
         </div>
+        <span v-if="item.validate" style="color: red">不能出现重复的值</span>
         <div class="tags">
         <div class="tags">
           <el-tag type="success" v-for="tag in item.tags" :key="tag.tag_id">{{
           <el-tag type="success" v-for="tag in item.tags" :key="tag.tag_id">{{
             tag.tag_name
             tag.tag_name

+ 1 - 1
src/components/rc-radio/rc-radio.vue

@@ -1,6 +1,6 @@
 <script lang="ts" name="rc-radio" setup>
 <script lang="ts" name="rc-radio" setup>
 import type { FormCreateProps } from '@form-create/element-ui'
 import type { FormCreateProps } from '@form-create/element-ui'
-import RcCreateOption from '../rc-options/rc-create-option.vue'
+import RcCreateOption from '../rc-options/create-option.vue'
 import { ref } from 'vue'
 import { ref } from 'vue'
 
 
 defineProps<{
 defineProps<{

+ 1 - 1
src/components/rc-select/rc-select.vue

@@ -1,6 +1,6 @@
 <script lang="ts" name="rc-select" setup>
 <script lang="ts" name="rc-select" setup>
 import type { FormCreateProps } from '@form-create/element-ui'
 import type { FormCreateProps } from '@form-create/element-ui'
-import RcCreateOption from '../rc-options/rc-create-option.vue'
+import RcCreateOption from '../rc-options/create-option.vue'
 
 
 defineProps<{
 defineProps<{
   formCreateInject: FormCreateProps & {
   formCreateInject: FormCreateProps & {

+ 75 - 0
src/components/rc-upload/rc-upload.vue

@@ -0,0 +1,75 @@
+<script lang="ts" setup name="rc-upload">
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { Plus } from '@element-plus/icons-vue'
+import type { UploadProps } from 'element-plus'
+import type { FormCreateProps } from '@form-create/element-ui'
+
+const props = defineProps<{
+  formCreateInject: FormCreateProps
+  value: string
+}>()
+
+const imageUrl = ref('')
+
+const ImgType = ['jpeg', 'png', 'gif']
+const validateFileType = (name: string) => {
+  const n = name.split('/')[1]
+  return !!ImgType.includes(n)
+}
+
+const handleAvatarSuccess: UploadProps['onChange'] = async (uploadFile) => {
+  const formData = new FormData()
+  formData.append('file', uploadFile.raw as Blob)
+  formData.append('access_token_openwork', localStorage.getItem('access_token_openwork')!)
+  const res = await window.__QIANKUN__REQUSET__?.Upload._getUrl(formData)
+  console.log(res)
+}
+
+const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
+  if (validateFileType(rawFile.type)) {
+    ElMessage.error('Avatar picture must be JPG, PNG, or GIF format!')
+    return false
+  } else if (rawFile.size / 1024 / 1024 > 2) {
+    ElMessage.error('Avatar picture size can not exceed 2MB!')
+    return false
+  }
+  return true
+}
+</script>
+<template>
+  <el-upload
+    class="avatar-uploader"
+    :show-file-list="false"
+    :auto-upload="false"
+    :on-change="handleAvatarSuccess"
+    :before-upload="beforeAvatarUpload"
+    v-bind="$attrs"
+  >
+    <img v-if="imageUrl" :src="imageUrl" class="avatar" />
+    <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
+  </el-upload>
+</template>
+
+<style>
+.avatar-uploader .el-upload {
+  border: 1px dashed var(--el-border-color);
+  border-radius: 6px;
+  cursor: pointer;
+  position: relative;
+  overflow: hidden;
+  transition: var(--el-transition-duration-fast);
+}
+
+.avatar-uploader .el-upload:hover {
+  border-color: var(--el-color-primary);
+}
+
+.el-icon.avatar-uploader-icon {
+  font-size: 28px;
+  color: #8c939d;
+  width: 178px;
+  height: 178px;
+  text-align: center;
+}
+</style>

+ 3 - 1
src/form.config.ts

@@ -4,6 +4,8 @@ import type { Config } from '@form-create/designer'
 export const formConfig: Config = {
 export const formConfig: Config = {
   //是否显示保存按钮
   //是否显示保存按钮
   showSaveBtn: true,
   showSaveBtn: true,
+  //配置设计区域显示方式
+  device: 'mobile',
   // 隐藏所有子表单组件
   // 隐藏所有子表单组件
   hiddenMenu: ['subform', 'aide', 'layout'],
   hiddenMenu: ['subform', 'aide', 'layout'],
   /**
   /**
@@ -73,7 +75,7 @@ export const formConfig: Config = {
   },
   },
   // 修改组件的默认信息
   // 修改组件的默认信息
   updateDefaultRule: {},
   updateDefaultRule: {},
-  // showDevice: false, // 隐藏多端适配选项
+  showDevice: false, // 隐藏多端适配选项
   showStyleForm: false, // 隐藏组件的样式配置
   showStyleForm: false, // 隐藏组件的样式配置
   showControl: false, // 隐藏组件的联动数据配置
   showControl: false, // 隐藏组件的联动数据配置
   // showPropsForm: false, // 隐藏组件的属性配置
   // showPropsForm: false, // 隐藏组件的属性配置

+ 7 - 17
src/main.ts

@@ -1,39 +1,29 @@
 /* eslint-disable @typescript-eslint/ban-ts-comment */
 /* eslint-disable @typescript-eslint/ban-ts-comment */
-/* eslint-disable @typescript-eslint/no-explicit-any */
-import { createApp } from 'vue'
+
+import { createApp, type App as AppType } from 'vue'
 
 
 import './main.css'
 import './main.css'
 import App from './App.vue'
 import App from './App.vue'
 import FcDesigner from '@form-create/designer'
 import FcDesigner from '@form-create/designer'
-import ELEMENT, { type MessageProps } from 'element-plus'
+import ELEMENT from 'element-plus'
 import 'element-plus/dist/index.css'
 import 'element-plus/dist/index.css'
 import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
 import { renderWithQiankun, qiankunWindow } from 'vite-plugin-qiankun/dist/helper'
 // @ts-ignore
 // @ts-ignore
-import { formCreate } from '@form-create/designer'
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
 
 
-let app: any = null
 //封装弹窗方法
 //封装弹窗方法
-import { ElMessage } from 'element-plus'
 import setupComponent from './components'
 import setupComponent from './components'
-const message = (msg: string, type: MessageProps['type']) => {
-  return ElMessage({
-    message: msg,
-    type: type || 'success',
-    customClass: '_fc-message-tip',
-  })
-}
+
+let app: AppType | null = null
 //导入方法
 //导入方法
-formCreate.setData('message', message)
 
 
 //导入方法
 //导入方法
 async function bootstrapVue3(container: HTMLElement) {
 async function bootstrapVue3(container: HTMLElement) {
-  await setupComponent()
-
   if (qiankunWindow.__POWERED_BY_QIANKUN__) {
   if (qiankunWindow.__POWERED_BY_QIANKUN__) {
     console.log('处于独立运行模式...')
     console.log('处于独立运行模式...')
   }
   }
   app = createApp(App)
   app = createApp(App)
+  await setupComponent(app)
   for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
     app.component(key, component)
     app.component(key, component)
   }
   }
@@ -63,7 +53,7 @@ const initQianKun = () => {
     update() {},
     update() {},
     unmount() {
     unmount() {
       // 卸载子应用
       // 卸载子应用
-      app.unmount()
+      app?.unmount()
       app = null
       app = null
     },
     },
   })
   })

+ 3 - 2
src/plugins/components/rc-checkbox.ts → src/plugins/components/rc-checkbox.config.ts

@@ -3,7 +3,7 @@ import type { DragRule } from '@form-create/designer'
 export const RcCheckbox: DragRule = {
 export const RcCheckbox: DragRule = {
   menu: 'aide',
   menu: 'aide',
   icon: 'icon-title',
   icon: 'icon-title',
-  label: '标题',
+  label: '多选框',
   //唯一 ID
   //唯一 ID
   name: 'rc-checkbox',
   name: 'rc-checkbox',
   //组件可以配置的事件
   //组件可以配置的事件
@@ -14,6 +14,7 @@ export const RcCheckbox: DragRule = {
     return {
     return {
       //组件的名称, 与上一步是对应
       //组件的名称, 与上一步是对应
       type: 'rc-checkbox',
       type: 'rc-checkbox',
+      title: '多选框',
       props: {
       props: {
         clearable: true,
         clearable: true,
       },
       },
@@ -27,7 +28,7 @@ export const RcCheckbox: DragRule = {
         field: 'options',
         field: 'options',
         title: '选项内容',
         title: '选项内容',
         props: {
         props: {
-          field: rule.field,
+          field: rule.field, // 设置组件唯一id从而保证多个组件的选项不冲突
         },
         },
       },
       },
     ]
     ]

+ 2 - 1
src/plugins/components/rc-radio.config.ts

@@ -3,7 +3,7 @@ import type { DragRule } from '@form-create/designer'
 export const RcRadio: DragRule = {
 export const RcRadio: DragRule = {
   menu: 'aide',
   menu: 'aide',
   icon: 'icon-title',
   icon: 'icon-title',
-  label: '标题',
+  label: '单选框',
   //唯一 ID
   //唯一 ID
   name: 'rc-radio',
   name: 'rc-radio',
   //组件可以配置的事件
   //组件可以配置的事件
@@ -14,6 +14,7 @@ export const RcRadio: DragRule = {
     return {
     return {
       //组件的名称, 与上一步是对应
       //组件的名称, 与上一步是对应
       type: 'rc-radio',
       type: 'rc-radio',
+      title: '单选框',
       props: {
       props: {
         clearable: true,
         clearable: true,
       },
       },

+ 2 - 1
src/plugins/components/rc-select.config.ts

@@ -3,7 +3,7 @@ import type { DragRule } from '@form-create/designer'
 export const RcSelect: DragRule = {
 export const RcSelect: DragRule = {
   menu: 'aide',
   menu: 'aide',
   icon: 'icon-title',
   icon: 'icon-title',
-  label: '标题',
+  label: '下拉框',
   //唯一 ID
   //唯一 ID
   name: 'rc-select',
   name: 'rc-select',
   //组件可以配置的事件
   //组件可以配置的事件
@@ -14,6 +14,7 @@ export const RcSelect: DragRule = {
     return {
     return {
       //组件的名称, 与上一步是对应
       //组件的名称, 与上一步是对应
       type: 'rc-select',
       type: 'rc-select',
+      title: '下拉框',
       props: {
       props: {
         placeholder: '请选择',
         placeholder: '请选择',
         clearable: true,
         clearable: true,

+ 34 - 0
src/plugins/components/rc-upload.config.ts

@@ -0,0 +1,34 @@
+import type { DragRule } from '@form-create/designer'
+
+export const RcUpload: DragRule = {
+  menu: 'aide',
+  icon: 'icon-title',
+  label: '图片',
+  //唯一 ID
+  name: 'rc-upload',
+  //组件可以配置的事件
+  input: true,
+  languageKey: [],
+  rule() {
+    //组件的渲染规则
+    return {
+      //组件的名称, 与上一步是对应
+      type: 'rc-upload',
+      title: '图片',
+      props: {},
+    }
+  },
+  props(rule) {
+    //组件右侧的配置项,与组件中的 props 对应
+    return [
+      {
+        type: 'rc-options',
+        field: 'options',
+        title: '选项内容',
+        props: {
+          field: rule.field,
+        },
+      },
+    ]
+  },
+}

+ 1 - 1
src/plugins/menu/options.ts

@@ -2,7 +2,7 @@ import type { Menu } from '@form-create/designer'
 
 
 export const MenuOptions: Menu = {
 export const MenuOptions: Menu = {
   title: '选项组件',
   title: '选项组件',
-  name: 'rc-component',
+  name: 'rc-options-component',
   list: [
   list: [
     {
     {
       name: 'rc-select',
       name: 'rc-select',

+ 13 - 0
src/plugins/menu/upload.ts

@@ -0,0 +1,13 @@
+import type { Menu } from '@form-create/designer'
+
+export const MenuUpload: Menu = {
+  title: '上传组件',
+  name: 'rc-upload-component',
+  list: [
+    {
+      name: 'rc-upload',
+      icon: 'icon-upload',
+      label: '图片',
+    },
+  ],
+}

部分文件因为文件数量过多而无法显示