Browse Source

feat: Form改造

kailong321200875 1 year ago
parent
commit
9c724dc9aa

+ 0 - 1
src/components/Form/index.ts

@@ -27,7 +27,6 @@ export type {
   TimeSelectComponentProps,
   ColProps,
   FormSetProps,
-  FormValueType,
   FormItemProps,
   FormSchema,
   FormProps,

+ 17 - 6
src/components/Form/src/Form.vue

@@ -182,11 +182,8 @@ export default defineComponent({
 
     // 渲染formItem
     const renderFormItem = (item: FormSchema) => {
-      const formItemSlots: Recordable = setFormItemSlots(slots, item.field)
-      return (
-        <ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
-          {{
-            default: () => {
+      const formItemSlots = {
+        default: () => {
               if (slots[item.field]) {
                 return getSlot(slots, item.field, formModel.value)
               } else {
@@ -257,7 +254,21 @@ export default defineComponent({
                   </Com>
                 )
               }
-            },
+            }
+      }
+      if (item?.formItemProps?.slots?.label) {
+        formItemSlots.label = (...args: any[]) => {
+          return item.formItemProps.slots.label(...args)
+        }
+      }
+      if (item?.formItemProps?.slots?.error) {
+        formItemSlots.error = (...args: any[]) => {
+          return item.formItemProps.slots.error(...args)
+        }
+      }
+      return (
+        <ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label || ''}>
+          {{
             ...formItemSlots
           }}
         </ElFormItem>

+ 0 - 22
src/components/Form/src/helper/index.ts

@@ -1,6 +1,4 @@
 import { useI18n } from '@/hooks/web/useI18n'
-import { type Slots } from 'vue'
-import { getSlot } from '@/utils/tsxHelper'
 import { PlaceholderModel, FormSchema, ComponentNameEnum, ColProps } from '../types'
 import { isFunction } from '@/utils/is'
 import { firstUpperCase, humpToDash } from '@/utils'
@@ -156,23 +154,3 @@ export const initModel = (schema: FormSchema[], formModel: Recordable) => {
   })
   return model
 }
-
-/**
- * @param slots 插槽
- * @param field 字段名
- * @returns 返回FormIiem插槽
- */
-export const setFormItemSlots = (slots: Slots, field: string): Recordable => {
-  const slotObj: Recordable = {}
-  if (slots[`${field}-error`]) {
-    slotObj['error'] = (...args: any[]) => {
-      return getSlot(slots, `${field}-error`, args)
-    }
-  }
-  if (slots[`${field}-label`]) {
-    slotObj['label'] = (...args: any[]) => {
-      return getSlot(slots, `${field}-label`, args)
-    }
-  }
-  return slotObj
-}

+ 6 - 21
src/components/Form/src/types/index.ts

@@ -53,7 +53,6 @@ type CamelCaseComponentName = keyof typeof ComponentNameEnum extends infer K
 export type ComponentName = CamelCaseComponentName
 
 export interface InputComponentProps {
-  value?: string | number
   maxlength?: number | string
   minlength?: number | string
   showWordLimit?: boolean
@@ -99,7 +98,6 @@ export interface InputComponentProps {
 }
 
 export interface AutocompleteComponentProps {
-  value?: string
   placeholder?: string
   clearable?: boolean
   disabled?: boolean
@@ -132,7 +130,6 @@ export interface AutocompleteComponentProps {
 }
 
 export interface InputNumberComponentProps {
-  value?: number
   min?: number
   max?: number
   step?: number
@@ -167,7 +164,6 @@ export interface SelectOption {
 }
 
 export interface SelectComponentProps {
-  value?: string | number | boolean | Object
   multiple?: boolean
   disabled?: boolean
   valueKey?: string
@@ -245,7 +241,6 @@ export interface SelectComponentProps {
 }
 
 export interface SelectV2ComponentProps {
-  value?: string | number | boolean | Object
   multiple?: boolean
   disabled?: boolean
   valueKey?: string
@@ -290,7 +285,6 @@ export interface SelectV2ComponentProps {
 }
 
 export interface CascaderComponentProps {
-  value?: string | number | string[] | number[] | any
   options?: Record<string, unknown>[]
   props?: CascaderProps
   size?: ElementPlusSize
@@ -325,7 +319,6 @@ export interface CascaderComponentProps {
 }
 
 export interface SwitchComponentProps {
-  value?: boolean | string | number
   disabled?: boolean
   loading?: boolean
   size?: ElementPlusSize
@@ -347,7 +340,6 @@ export interface SwitchComponentProps {
 }
 
 export interface RateComponentProps {
-  value?: number
   max?: number
   size?: ElementPlusSize
   disabled?: boolean
@@ -375,7 +367,6 @@ export interface RateComponentProps {
 }
 
 export interface ColorPickerComponentProps {
-  value?: string
   disabled?: boolean
   size?: ElementPlusSize
   showAlpha?: boolean
@@ -393,7 +384,6 @@ export interface ColorPickerComponentProps {
 }
 
 export interface TransferComponentProps {
-  value?: any[]
   data?: any[]
   filterable?: boolean
   filterPlaceholder?: string
@@ -444,7 +434,6 @@ export interface RadioOption {
   [key: string]: any
 }
 export interface RadioGroupComponentProps {
-  value?: string | number | boolean
   size?: ElementPlusSize
   disabled?: boolean
   textColor?: string
@@ -472,7 +461,6 @@ export interface RadioGroupComponentProps {
 }
 
 export interface RadioButtonComponentProps {
-  value?: string | number | boolean
   size?: ElementPlusSize
   disabled?: boolean
   textColor?: string
@@ -518,7 +506,6 @@ export interface CheckboxOption {
 }
 
 export interface CheckboxGroupComponentProps {
-  value?: string[] | number[]
   size?: ElementPlusSize
   disabled?: boolean
   min?: number
@@ -547,7 +534,6 @@ export interface CheckboxGroupComponentProps {
 }
 
 export interface DividerComponentProps {
-  value?: number | Array<number>
   min?: number
   max?: number
   disabled?: boolean
@@ -579,7 +565,6 @@ export interface DividerComponentProps {
 }
 
 export interface DatePickerComponentProps {
-  value?: string | Date | number | string[]
   readonly?: boolean
   disabled?: boolean
   size?: ElementPlusSize
@@ -631,7 +616,6 @@ export interface DatePickerComponentProps {
 }
 
 export interface DateTimePickerComponentProps {
-  value?: string | Date | number | string[]
   readonly?: boolean
   disabled?: boolean
   editable?: boolean
@@ -672,7 +656,6 @@ export interface DateTimePickerComponentProps {
 }
 
 export interface TimePickerComponentProps {
-  value?: string | Date | number | [Date, Date] | [number, number] | [string, string]
   readonly?: boolean
   disabled?: boolean
   editable?: boolean
@@ -709,7 +692,6 @@ export interface TimePickerComponentProps {
 }
 
 export interface TimeSelectComponentProps {
-  value?: string
   disabled?: boolean
   editable?: boolean
   clearable?: boolean
@@ -754,8 +736,6 @@ export interface FormSetProps {
   value: any
 }
 
-export type FormValueType = string | number | string[] | number[] | boolean | undefined | null
-
 export interface FormItemProps {
   labelWidth?: string | number
   required?: boolean
@@ -767,6 +747,11 @@ export interface FormItemProps {
   for?: string
   validateStatus?: '' | 'error' | 'validating' | 'success'
   style?: CSSProperties
+  slots?: {
+    default?: (...args: any[]) => JSX.Element | null
+    label?: (...args: any[]) => JSX.Element | null
+    error?: (...args: any[]) => JSX.Element | null
+  }
 }
 
 export interface FormSchema {
@@ -825,7 +810,7 @@ export interface FormSchema {
   /**
    * 初始值
    */
-  value?: FormValueType
+  value?: any
 
   /**
    * 是否隐藏

+ 3 - 6
src/hooks/web/useForm.ts

@@ -1,10 +1,9 @@
 import type { Form, FormExpose } from '@/components/Form'
 import type { ElForm } from 'element-plus'
 import { ref, unref, nextTick } from 'vue'
-import type { FormProps } from '@/components/Form/src/types'
-import { FormSchema, FormSetPropsType } from '@/types/form'
+import { FormSchema, FormSetProps, FormProps } from '@/components/Form'
 
-export const useForm = (props?: FormProps) => {
+export const useForm = () => {
   // From实例
   const formRef = ref<typeof Form & FormExpose>()
 
@@ -47,7 +46,7 @@ export const useForm = (props?: FormProps) => {
     /**
      * @param schemaProps 需要设置的schemaProps
      */
-    setSchema: async (schemaProps: FormSetPropsType[]) => {
+    setSchema: async (schemaProps: FormSetProps[]) => {
       const form = await getForm()
       form?.setSchema(schemaProps)
     },
@@ -78,8 +77,6 @@ export const useForm = (props?: FormProps) => {
     }
   }
 
-  props && methods.setProps(props)
-
   return {
     register,
     formRef: elFormRef,

+ 20 - 18
src/views/Components/Form/DefaultForm.vue

@@ -23,8 +23,6 @@ const { t } = useI18n()
 
 const isMobile = computed(() => appStore.getMobile)
 
-const toggle = ref(false)
-
 const restaurants = ref<Recordable[]>([])
 const querySearch = (queryString: string, cb: Fn) => {
   const results = queryString
@@ -679,7 +677,6 @@ const schema = reactive<FormSchema[]>([
                 return (
                   <ElOption
                     key={v.value}
-                    disabled={unref(toggle)}
                     label={v.label}
                     value={v.value}
                   />
@@ -1379,32 +1376,37 @@ const schema = reactive<FormSchema[]>([
   {
     field: 'field68',
     component: 'Divider',
-    label: `${t('formDemo.form')} t('formDemo.slot')}`,
+    label: `${t('formDemo.form')} ${t('formDemo.slot')}`,
   },
   {
     field: 'field69',
     component: 'Input',
-    value: 'test',
-    label: `default`,
+    label: `label`,
+    formItemProps: {
+      slots: {
+        label: ({ label }) => {
+          return (
+            <div class="custom-label">
+              <span class="label-text">custom {label}</span>
+            </div>
+          )
+        }
+      }
+    }
   },
 ])
 
-const { register, formRef, methods } = useForm({
-  schema,
-  labelWidth: 'auto',
-  labelPosition: isMobile.value ? 'top' : 'right'
-})
-
-const changeToggle = () => {
-  toggle.value = !unref(toggle)
-}
+const { register, formRef, methods } = useForm()
 </script>
 
 <template>
-  <button @click="changeToggle">测试</button>
   <ContentWrap :title="t('formDemo.defaultForm')" :message="t('formDemo.formDes')">
-    <Form @register="register" label-width="auto" :label-position="isMobile ? 'top' : 'right'">
-    </Form>
+    <Form
+      @register="register"
+      :schema="schema"
+      label-width="auto"
+      :label-position="isMobile ? 'top' : 'right'"
+    />
   </ContentWrap>
 </template>