Эх сурвалжийг харах

feat(VForm): Add VForm component

kailong321200875 3 жил өмнө
parent
commit
448ac5293e

+ 14 - 15
pnpm-lock.yaml

@@ -6128,8 +6128,8 @@ packages:
       vue-i18n:
         optional: true
     dependencies:
-      '@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.23
-      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23
+      '@intlify/message-compiler': registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.25
+      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
       jsonc-eslint-parser: registry.npmmirror.com/jsonc-eslint-parser/1.4.1
       source-map: registry.nlark.com/source-map/0.6.1
       vue-i18n: registry.npmmirror.com/vue-i18n/9.1.9_vue@3.2.24
@@ -6185,18 +6185,18 @@ packages:
       source-map: registry.nlark.com/source-map/0.6.1
     dev: false
 
-  registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.23:
+  registry.npmmirror.com/@intlify/message-compiler/9.2.0-beta.25:
     resolution:
       {
-        integrity: sha512-qmGN8k5yGGdZ5St8yg8U4Tg2K9Sc6h3BhWCdJKAqQVs5jnfZG+nMtsLVgnJUWkDvhjzyg7/rEOhHm2uJcu4vjw==,
+        integrity: sha512-/YMG6LmQLvD8uHCJvWLaK0t8exYbek3ya4BZZ99AcM5+JC/JRdLIK8WiVJnGpfrvleQArxvHed4GokS+oWZ5rQ==,
         registry: https://registry.npm.taobao.org/,
-        tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.23.tgz
+        tarball: https://registry.npmmirror.com/@intlify/message-compiler/download/@intlify/message-compiler-9.2.0-beta.25.tgz
       }
     name: '@intlify/message-compiler'
-    version: 9.2.0-beta.23
+    version: 9.2.0-beta.25
     engines: { node: '>= 12' }
     dependencies:
-      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23
+      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
       source-map: registry.nlark.com/source-map/0.6.1
     dev: true
 
@@ -6240,15 +6240,15 @@ packages:
     engines: { node: '>= 10' }
     dev: false
 
-  registry.npmmirror.com/@intlify/shared/9.2.0-beta.23:
+  registry.npmmirror.com/@intlify/shared/9.2.0-beta.25:
     resolution:
       {
-        integrity: sha512-3aELL2KTp1MWKGm2gIUKSagthgKzcK5hpQEFzOwkJ1SAthpTXR7BHeWGEaD+Lj+Pbiz3U8cspvp8s2lFWVbYxg==,
+        integrity: sha512-I2L05aWh0azr5KwQjLV7gMTN0SrdglgMAfpJniT53Pvvc8l+OTs8IEhdPCQwsbgOravpWt14O7m3deOzw3ln6w==,
         registry: https://registry.npm.taobao.org/,
-        tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.23.tgz
+        tarball: https://registry.npmmirror.com/@intlify/shared/download/@intlify/shared-9.2.0-beta.25.tgz
       }
     name: '@intlify/shared'
-    version: 9.2.0-beta.23
+    version: 9.2.0-beta.25
     engines: { node: '>= 12' }
     dev: true
 
@@ -6274,7 +6274,7 @@ packages:
         optional: true
     dependencies:
       '@intlify/bundle-utils': registry.npmmirror.com/@intlify/bundle-utils/2.2.0_vue-i18n@9.1.9
-      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.23
+      '@intlify/shared': registry.npmmirror.com/@intlify/shared/9.2.0-beta.25
       '@rollup/pluginutils': registry.nlark.com/@rollup/pluginutils/4.1.1
       debug: registry.npmmirror.com/debug/4.3.3
       fast-glob: registry.nlark.com/fast-glob/3.2.7
@@ -8693,13 +8693,12 @@ packages:
   registry.npmmirror.com/lodash/4.17.21:
     resolution:
       {
-        integrity: sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=,
+        integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==,
         registry: https://registry.npm.taobao.org/,
         tarball: https://registry.npmmirror.com/lodash/download/lodash-4.17.21.tgz
       }
     name: lodash
     version: 4.17.21
-    dev: false
 
   registry.npmmirror.com/log-update/4.0.0:
     resolution:
@@ -10291,7 +10290,7 @@ packages:
     version: 0.3.2
     dependencies:
       eslint-visitor-keys: registry.npmmirror.com/eslint-visitor-keys/1.3.0
-      lodash: registry.nlark.com/lodash/4.17.21
+      lodash: registry.npmmirror.com/lodash/4.17.21
       yaml: registry.npmmirror.com/yaml/1.10.2
     dev: true
 

+ 442 - 98
src/App.vue

@@ -45,13 +45,13 @@ onMounted(() => {
 })
 
 const initials = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
-const options = ref<FormOptions[]>(
+const options = ref<ComponentOptions[]>(
   Array.from({ length: 1000 }).map((_, idx) => ({
     value: `Option ${idx + 1}`,
     label: `${initials[idx % 10]}${idx}`
   }))
 )
-const options2 = ref<FormOptions[]>(
+const options2 = ref<ComponentOptions[]>(
   Array.from({ length: 10 }).map((_, idx) => {
     const label = idx + 1
     return {
@@ -65,7 +65,7 @@ const options2 = ref<FormOptions[]>(
   })
 )
 
-const options3: FormOptions[] = [
+const options3: ComponentOptions[] = [
   {
     value: 'guide',
     label: 'Guide',
@@ -332,6 +332,20 @@ function generateData() {
   return data
 }
 
+const holidays = [
+  '2021-10-01',
+  '2021-10-02',
+  '2021-10-03',
+  '2021-10-04',
+  '2021-10-05',
+  '2021-10-06',
+  '2021-10-07'
+]
+
+function isHoliday({ dayjs }) {
+  return holidays.includes(dayjs.format('YYYY-MM-DD'))
+}
+
 const schema = reactive<VFormSchema[]>([
   {
     field: 'field1',
@@ -438,99 +452,107 @@ const schema = reactive<VFormSchema[]>([
     field: 'field14',
     label: t('formDemo.default'),
     component: 'Select',
-    options: [
-      {
-        label: '选项1',
-        value: '1'
-      },
-      {
-        label: '选项2',
-        value: '2'
-      }
-    ]
+    componentProps: {
+      options: [
+        {
+          label: 'option1',
+          value: '1'
+        },
+        {
+          label: 'option2',
+          value: '2'
+        }
+      ]
+    }
   },
   {
     field: 'field15',
     label: t('formDemo.slot'),
     component: 'Select',
-    options: [
-      {
-        label: '选项1',
-        value: '1'
-      },
-      {
-        label: '选项2',
-        value: '2'
-      }
-    ],
-    optionsSlot: true
+    componentProps: {
+      options: [
+        {
+          label: 'option1',
+          value: '1'
+        },
+        {
+          label: 'option2',
+          value: '2'
+        }
+      ],
+      optionsSlot: true
+    }
   },
   {
     field: 'field16',
-    label: t('formDemo.group'),
+    label: t('formDemo.selectGroup'),
     component: 'Select',
-    options: [
-      {
-        label: '选项1',
-        options: [
-          {
-            label: '选项1-1',
-            value: '1-1'
-          },
-          {
-            label: '选项1-2',
-            value: '1-2'
-          }
-        ]
-      },
-      {
-        label: '选项2',
-        options: [
-          {
-            label: '选项2-1',
-            value: '2-1'
-          },
-          {
-            label: '选项2-2',
-            value: '2-2'
-          }
-        ]
-      }
-    ]
+    componentProps: {
+      options: [
+        {
+          label: 'option1',
+          options: [
+            {
+              label: 'option1-1',
+              value: '1-1'
+            },
+            {
+              label: 'option1-2',
+              value: '1-2'
+            }
+          ]
+        },
+        {
+          label: 'option2',
+          options: [
+            {
+              label: 'option2-1',
+              value: '2-1'
+            },
+            {
+              label: 'option2-2',
+              value: '2-2'
+            }
+          ]
+        }
+      ]
+    }
   },
   {
     field: 'field17',
-    label: `${t('formDemo.group')}${t('formDemo.slot')}`,
+    label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
     component: 'Select',
-    options: [
-      {
-        label: '选项1',
-        options: [
-          {
-            label: '选项1-1',
-            value: '1-1'
-          },
-          {
-            label: '选项1-2',
-            value: '1-2'
-          }
-        ]
-      },
-      {
-        label: '选项2',
-        options: [
-          {
-            label: '选项2-1',
-            value: '2-1'
-          },
-          {
-            label: '选项2-2',
-            value: '2-2'
-          }
-        ]
-      }
-    ],
-    optionsSlot: true
+    componentProps: {
+      options: [
+        {
+          label: 'option1',
+          options: [
+            {
+              label: 'option1-1',
+              value: '1-1'
+            },
+            {
+              label: 'option1-2',
+              value: '1-2'
+            }
+          ]
+        },
+        {
+          label: 'option2',
+          options: [
+            {
+              label: 'option2-1',
+              value: '2-1'
+            },
+            {
+              label: 'option2-2',
+              value: '2-2'
+            }
+          ]
+        }
+      ],
+      optionsSlot: true
+    }
   },
   {
     field: 'field18',
@@ -541,14 +563,16 @@ const schema = reactive<VFormSchema[]>([
     field: 'field19',
     label: t('formDemo.default'),
     component: 'SelectV2',
-    options: options.value
+    componentProps: {
+      options: options.value
+    }
   },
   {
     field: 'field20',
     label: t('formDemo.slot'),
     component: 'SelectV2',
-    options: options.value,
     componentProps: {
+      options: options.value,
       slots: {
         default: true
       }
@@ -556,16 +580,18 @@ const schema = reactive<VFormSchema[]>([
   },
   {
     field: 'field21',
-    label: t('formDemo.group'),
+    label: t('formDemo.selectGroup'),
     component: 'SelectV2',
-    options: options2.value
+    componentProps: {
+      options: options2.value
+    }
   },
   {
     field: 'field22',
-    label: `${t('formDemo.group')}${t('formDemo.slot')}`,
+    label: `${t('formDemo.selectGroup')}${t('formDemo.slot')}`,
     component: 'SelectV2',
-    options: options2.value,
     componentProps: {
+      options: options2.value,
       slots: {
         default: true
       }
@@ -580,14 +606,16 @@ const schema = reactive<VFormSchema[]>([
     field: 'field24',
     label: t('formDemo.default'),
     component: 'Cascader',
-    options: options3
+    componentProps: {
+      options: options3
+    }
   },
   {
     field: 'field25',
     label: t('formDemo.slot'),
     component: 'Cascader',
-    options: options3,
     componentProps: {
+      options: options3,
       slots: {
         default: true
       }
@@ -710,15 +738,286 @@ const schema = reactive<VFormSchema[]>([
     colProps: {
       xl: 12
     }
+  },
+  {
+    field: 'field38',
+    label: t('formDemo.radio'),
+    component: 'Divider'
+  },
+  {
+    field: 'field39',
+    label: t('formDemo.default'),
+    component: 'Radio',
+    componentProps: {
+      options: [
+        {
+          label: 'option-1',
+          value: '1'
+        },
+        {
+          label: 'option-2',
+          value: '2'
+        }
+      ]
+    }
+  },
+  {
+    field: 'field40',
+    label: t('formDemo.button'),
+    component: 'RadioButton',
+    componentProps: {
+      options: [
+        {
+          label: 'option-1',
+          value: '1'
+        },
+        {
+          label: 'option-2',
+          value: '2'
+        }
+      ]
+    }
+  },
+  {
+    field: 'field41',
+    label: t('formDemo.checkbox'),
+    component: 'Divider'
+  },
+  {
+    field: 'field42',
+    label: t('formDemo.default'),
+    component: 'Checkbox',
+    value: [],
+    componentProps: {
+      options: [
+        {
+          label: 'option-1',
+          value: '1'
+        },
+        {
+          label: 'option-2',
+          value: '2'
+        },
+        {
+          label: 'option-3',
+          value: '23'
+        }
+      ]
+    }
+  },
+  {
+    field: 'field43',
+    label: t('formDemo.button'),
+    component: 'CheckboxButton',
+    value: [],
+    componentProps: {
+      options: [
+        {
+          label: 'option-1',
+          value: '1'
+        },
+        {
+          label: 'option-2',
+          value: '2'
+        },
+        {
+          label: 'option-3',
+          value: '23'
+        }
+      ]
+    }
+  },
+  {
+    field: 'field44',
+    component: 'Divider',
+    label: t('formDemo.slider')
+  },
+  {
+    field: 'field45',
+    component: 'Slider',
+    label: t('formDemo.default'),
+    value: 0
+  },
+  {
+    field: 'field46',
+    component: 'Divider',
+    label: t('formDemo.datePicker')
+  },
+  {
+    field: 'field47',
+    component: 'DatePicker',
+    label: t('formDemo.default'),
+    componentProps: {
+      type: 'date'
+    }
+  },
+  {
+    field: 'field48',
+    component: 'DatePicker',
+    label: t('formDemo.shortcuts'),
+    componentProps: {
+      type: 'date',
+      disabledDate: (time: Date) => {
+        return time.getTime() > Date.now()
+      },
+      shortcuts: [
+        {
+          text: t('formDemo.today'),
+          value: new Date()
+        },
+        {
+          text: t('formDemo.yesterday'),
+          value: () => {
+            const date = new Date()
+            date.setTime(date.getTime() - 3600 * 1000 * 24)
+            return date
+          }
+        },
+        {
+          text: t('formDemo.aWeekAgo'),
+          value: () => {
+            const date = new Date()
+            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
+            return date
+          }
+        }
+      ]
+    }
+  },
+  {
+    field: 'field49',
+    component: 'DatePicker',
+    label: t('formDemo.week'),
+    componentProps: {
+      type: 'week',
+      format: `[${t('formDemo.week')}] ww`
+    }
+  },
+  {
+    field: 'field50',
+    component: 'DatePicker',
+    label: t('formDemo.year'),
+    componentProps: {
+      type: 'year'
+    }
+  },
+  {
+    field: 'field51',
+    component: 'DatePicker',
+    label: t('formDemo.month'),
+    componentProps: {
+      type: 'month'
+    }
+  },
+  {
+    field: 'field52',
+    component: 'DatePicker',
+    label: t('formDemo.dates'),
+    componentProps: {
+      type: 'dates'
+    }
+  },
+  {
+    field: 'field53',
+    component: 'DatePicker',
+    label: t('formDemo.daterange'),
+    componentProps: {
+      type: 'daterange'
+    }
+  },
+  {
+    field: 'field54',
+    component: 'DatePicker',
+    label: t('formDemo.monthrange'),
+    componentProps: {
+      type: 'monthrange'
+    }
+  },
+  {
+    field: 'field55',
+    component: 'DatePicker',
+    label: t('formDemo.slot'),
+    componentProps: {
+      type: 'date',
+      format: 'YYYY/MM/DD',
+      valueFormat: 'YYYY-MM-DD',
+      slots: {
+        default: true
+      }
+    }
+  },
+  {
+    field: 'field56',
+    component: 'Divider',
+    label: t('formDemo.dateTimePicker')
+  },
+  {
+    field: 'field57',
+    component: 'DatePicker',
+    label: t('formDemo.default'),
+    componentProps: {
+      type: 'datetime'
+    }
+  },
+  {
+    field: 'field58',
+    component: 'DatePicker',
+    label: t('formDemo.shortcuts'),
+    componentProps: {
+      type: 'datetime',
+      shortcuts: [
+        {
+          text: t('formDemo.today'),
+          value: new Date()
+        },
+        {
+          text: t('formDemo.yesterday'),
+          value: () => {
+            const date = new Date()
+            date.setTime(date.getTime() - 3600 * 1000 * 24)
+            return date
+          }
+        },
+        {
+          text: t('formDemo.aWeekAgo'),
+          value: () => {
+            const date = new Date()
+            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
+            return date
+          }
+        }
+      ]
+    }
+  },
+  {
+    field: 'field59',
+    component: 'DatePicker',
+    label: t('formDemo.dateTimerange'),
+    componentProps: {
+      type: 'datetimerange'
+    }
+  },
+  {
+    field: 'field60',
+    component: 'Divider',
+    label: t('formDemo.timePicker')
+  },
+  {
+    field: 'field61',
+    component: 'TimePicker',
+    label: t('formDemo.default')
+  },
+  {
+    field: 'field62',
+    component: 'Divider',
+    label: t('formDemo.timeSelect')
+  },
+  {
+    field: 'field63',
+    component: 'TimeSelect',
+    label: t('formDemo.default')
   }
 ])
-
-setTimeout(() => {
-  if (schema[2].componentProps) {
-    schema[2].componentProps.placeholder = 'test'
-    console.log(schema[2])
-  }
-}, 3000)
 </script>
 
 <template>
@@ -775,6 +1074,51 @@ setTimeout(() => {
       <template #field36-default="{ option }">
         <span>{{ option.value }} - {{ option.desc }}</span>
       </template>
+
+      <template #field55-default="cell">
+        <div class="cell" :class="{ current: cell.isCurrent }">
+          <span class="text">{{ cell.text }}</span>
+          <span v-if="isHoliday(cell)" class="holiday"></span>
+        </div>
+      </template>
     </VFrom>
   </ElConfigProvider>
 </template>
+
+<style lang="less" scoped>
+.cell {
+  height: 30px;
+  padding: 3px 0;
+  box-sizing: border-box;
+
+  .text {
+    position: absolute;
+    left: 50%;
+    display: block;
+    width: 24px;
+    height: 24px;
+    margin: 0 auto;
+    line-height: 24px;
+    border-radius: 50%;
+    transform: translateX(-50%);
+  }
+
+  &.current {
+    .text {
+      color: #fff;
+      background: purple;
+    }
+  }
+
+  .holiday {
+    position: absolute;
+    bottom: 0px;
+    left: 50%;
+    width: 6px;
+    height: 6px;
+    background: red;
+    border-radius: 50%;
+    transform: translateX(-50%);
+  }
+}
+</style>

+ 19 - 4
src/components/Form/src/VForm.vue

@@ -12,6 +12,8 @@ import {
   setModel
 } from './helper'
 import { useRenderSelect } from './components/useRenderSelect'
+import { useRenderRadio } from './components/useRenderRadio'
+import { useRenderChcekbox } from './components/useRenderChcekbox'
 
 export default defineComponent({
   name: 'VForm',
@@ -93,7 +95,11 @@ export default defineComponent({
       const slotsMap: Recordable = {
         ...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
       }
-      if (item?.component !== 'SelectV2' && item.options) {
+      if (
+        item?.component !== 'SelectV2' &&
+        item?.component !== 'Cascader' &&
+        item?.componentProps?.options
+      ) {
         slotsMap.default = () => renderOptions(item)
       }
       return (
@@ -105,8 +111,9 @@ export default defineComponent({
                 vModel={formModel[item.field]}
                 {...(autoSetPlaceholder && setTextPlaceholder(item))}
                 {...setComponentProps(item)}
-                {...(notRenderOptions.includes(item?.component as string) && item.options
-                  ? { options: item.options || [] }
+                {...(notRenderOptions.includes(item?.component as string) &&
+                item?.componentProps?.options
+                  ? { options: item?.componentProps?.options || [] }
                   : {})}
               >
                 {{ ...slotsMap }}
@@ -123,6 +130,14 @@ export default defineComponent({
         case 'Select':
           const { renderSelectOptions } = useRenderSelect(slots)
           return renderSelectOptions(item)
+        case 'Radio':
+        case 'RadioButton':
+          const { renderRadioOptions } = useRenderRadio()
+          return renderRadioOptions(item)
+        case 'Checkbox':
+        case 'CheckboxButton':
+          const { renderChcekboxOptions } = useRenderChcekbox()
+          return renderChcekboxOptions(item)
         default:
           break
       }
@@ -142,7 +157,7 @@ export default defineComponent({
     }
 
     return () => (
-      <ElForm ref={formRef} {...getFormBindValue()} model={formModel}>
+      <ElForm ref={formRef} {...getFormBindValue()} model={formModel} class="v-form">
         {{
           // 如果需要自定义,就什么都不渲染,而是提供默认插槽
           default: () => (isCustom ? getSlot(slots, 'default') : renderWrap())

+ 3 - 1
src/components/Form/src/componentMap.ts

@@ -22,6 +22,7 @@ import {
 const componentMap: Recordable<Component, ComponentName> = {
   Radio: ElRadioGroup,
   Checkbox: ElCheckboxGroup,
+  CheckboxButton: ElCheckboxGroup,
   Input: ElInput,
   Autocomplete: ElAutocomplete,
   InputNumber: ElInputNumber,
@@ -36,7 +37,8 @@ const componentMap: Recordable<Component, ComponentName> = {
   Transfer: ElTransfer,
   Divider: ElDivider,
   TimeSelect: ElTimeSelect,
-  SelectV2: ElSelectV2
+  SelectV2: ElSelectV2,
+  RadioButton: ElRadioGroup
 }
 
 export { componentMap }

+ 20 - 0
src/components/Form/src/components/useRenderChcekbox.tsx

@@ -0,0 +1,20 @@
+import { ElCheckbox, ElCheckboxButton } from 'element-plus'
+import { defineComponent } from 'vue'
+
+export function useRenderChcekbox() {
+  function renderChcekboxOptions(item: VFormSchema) {
+    // 如果有别名,就取别名
+    const labelAlias = item?.componentProps?.optionsAlias?.labelField
+    const valueAlias = item?.componentProps?.optionsAlias?.valueField
+    const Com = (item.component === 'Checkbox' ? ElCheckbox : ElCheckboxButton) as ReturnType<
+      typeof defineComponent
+    >
+    return item?.componentProps?.options?.map((option) => {
+      return <Com label={option[labelAlias || 'value']}>{option[valueAlias || 'label']}</Com>
+    })
+  }
+
+  return {
+    renderChcekboxOptions
+  }
+}

+ 20 - 0
src/components/Form/src/components/useRenderRadio.tsx

@@ -0,0 +1,20 @@
+import { ElRadio, ElRadioButton } from 'element-plus'
+import { defineComponent } from 'vue'
+
+export function useRenderRadio() {
+  function renderRadioOptions(item: VFormSchema) {
+    // 如果有别名,就取别名
+    const labelAlias = item?.componentProps?.optionsAlias?.labelField
+    const valueAlias = item?.componentProps?.optionsAlias?.valueField
+    const Com = (item.component === 'Radio' ? ElRadio : ElRadioButton) as ReturnType<
+      typeof defineComponent
+    >
+    return item?.componentProps?.options?.map((option) => {
+      return <Com label={option[labelAlias || 'value']}>{option[valueAlias || 'label']}</Com>
+    })
+  }
+
+  return {
+    renderRadioOptions
+  }
+}

+ 10 - 11
src/components/Form/src/components/useRenderSelect.tsx

@@ -6,11 +6,11 @@ export function useRenderSelect(slots: Slots) {
   // 渲染 select options
   function renderSelectOptions(item: VFormSchema) {
     // 如果有别名,就取别名
-    const labelAlias = item.optionsField?.labelField
-    return item.options?.map((option) => {
+    const labelAlias = item?.componentProps?.optionsAlias?.labelField
+    return item?.componentProps?.options?.map((option) => {
       if (option?.options?.length) {
         return (
-          <ElOptionGroup label={labelAlias ? option[labelAlias] : option['label']}>
+          <ElOptionGroup label={option[labelAlias || 'label']}>
             {() => {
               return option?.options?.map((v) => {
                 return renderSelectOptionItem(item, v)
@@ -25,19 +25,18 @@ export function useRenderSelect(slots: Slots) {
   }
 
   // 渲染 select option item
-  function renderSelectOptionItem(item: VFormSchema, option: FormOptions) {
+  function renderSelectOptionItem(item: VFormSchema, option: ComponentOptions) {
     // 如果有别名,就取别名
-    const labelAlias = item.optionsField?.labelField
-    const valueAlias = item.optionsField?.valueField
+    const labelAlias = item?.componentProps?.optionsAlias?.labelField
+    const valueAlias = item?.componentProps?.optionsAlias?.valueField
     return (
-      <ElOption
-        label={labelAlias ? option[labelAlias] : option['label']}
-        value={valueAlias ? option[valueAlias] : option['value']}
-      >
+      <ElOption label={option[labelAlias || 'label']} value={option[valueAlias || 'value']}>
         {{
           default: () =>
             // option 插槽名规则,{field}-option
-            item.optionsSlot ? getSlot(slots, `${item.field}-option`, { item: option }) : undefined
+            item?.componentProps?.optionsSlot
+              ? getSlot(slots, `${item.field}-option`, { item: option })
+              : undefined
         }}
       </ElOption>
     )

+ 22 - 3
src/locales/en.ts

@@ -16,13 +16,32 @@ export default {
     position: 'Position',
     autocomplete: 'Autocomplete',
     select: 'Select',
-    group: 'Select Group',
+    selectGroup: 'Select Group',
     selectV2: 'SelectV2',
     cascader: 'Cascader',
     switch: 'Switch',
     rate: 'Rate',
-    colorPicker: 'ColorPicker',
+    colorPicker: 'Color Picker',
     transfer: 'Transfer',
-    render: 'Render'
+    render: 'Render',
+    radio: 'Radio',
+    button: 'Button',
+    checkbox: 'Checkbox',
+    slider: 'Slider',
+    datePicker: 'Date Picker',
+    shortcuts: 'Shortcuts',
+    today: 'Today',
+    yesterday: 'Yesterday',
+    aWeekAgo: 'A week ago',
+    week: 'Week',
+    year: 'Year',
+    month: 'Month',
+    dates: 'Dates',
+    daterange: 'Date Range',
+    monthrange: 'Month Range',
+    dateTimePicker: 'DateTimePicker',
+    dateTimerange: 'Datetime Range',
+    timePicker: 'Time Picker',
+    timeSelect: 'Time Select'
   }
 }

+ 21 - 2
src/locales/zh-CN.ts

@@ -16,13 +16,32 @@ export default {
     position: '位置',
     autocomplete: '自动补全',
     select: '选择器',
-    group: '选项分组',
+    selectGroup: '选项分组',
     selectV2: '虚拟列表选择器',
     cascader: '级联选择器',
     switch: '开关',
     rate: '评分',
     colorPicker: '颜色选择器',
     transfer: '穿梭框',
-    render: '渲染器'
+    render: '渲染器',
+    radio: '单选框',
+    button: '按钮',
+    checkbox: '多选框',
+    slider: '滑块',
+    datePicker: '日期选择器',
+    shortcuts: '快捷选项',
+    today: '今天',
+    yesterday: '昨天',
+    aWeekAgo: '一周前',
+    week: '周',
+    year: '年',
+    month: '月',
+    dates: '日期',
+    daterange: '日期范围',
+    monthrange: '月份范围',
+    dateTimePicker: '日期时间选择器',
+    dateTimerange: '日期时间范围',
+    timePicker: '时间选择器',
+    timeSelect: '时间选择'
   }
 }

+ 0 - 0
src/styles/variable.less → src/styles/variables.less


+ 14 - 15
src/types/componentType.d.ts

@@ -5,7 +5,9 @@ declare global {
   // BfForm types start
   declare type ComponentName =
     | 'Radio'
+    | 'RadioButton'
     | 'Checkbox'
+    | 'CheckboxButton'
     | 'Input'
     | 'Autocomplete'
     | 'InputNumber'
@@ -52,21 +54,26 @@ declare global {
     style?: CSSProperties
   }
 
-  declare type FormOptions = {
+  declare type ComponentOptions = {
     label?: string
     value?: FormValueTypes
     disabled?: boolean
     key?: string | number
-    children?: FormOptions[]
-    options?: FormOptions[]
-    [key: string]: any
-  }
+    children?: ComponentOptions[]
+    options?: ComponentOptions[]
+  } & Recordable
 
-  declare type FormOptionsAlias = {
+  declare type ComponentOptionsAlias = {
     labelField?: string
     valueField?: string
   }
 
+  declare type ComponentProps = {
+    optionsAlias?: ComponentOptionsAlias
+    options?: ComponentOptions[]
+    optionsSlot?: boolean
+  } & Recordable
+
   declare type VFormSchema = {
     // 唯一值
     field: string
@@ -75,23 +82,15 @@ declare global {
     // col组件属性
     colProps?: ColProps
     // 表单组件属性,slots对应的是表单组件的插槽,规则:${field}-xxx,具体可以查看element-plus文档
-    componentProps?: { slots?: Recordable } & Recordable
+    componentProps?: { slots?: Recordable } & ComponentProps
     // formItem组件属性
     formItemProps?: FormItemProps
     // 渲染的组件
     component?: ComponentName
     // 初始值
     value?: FormValueTypes
-    // 下拉选项
-    options?: FormOptions[]
-    // 下拉选项别名
-    optionsField?: FormOptionsAlias
-    // 下拉选项插槽,规则:${field}-option
-    optionsSlot?: boolean
     // 是否隐藏
     hidden?: boolean
-    // 表单组件插槽,规则:${field}
-    slot?: boolean
   }
 
   // VForm types end