Browse Source

wip(VForm): VForm component development

陈凯龙 3 years ago
parent
commit
d16a5aa75e

+ 96 - 0
src/App.vue

@@ -316,6 +316,22 @@ const options3: FormOptions[] = [
   }
 ]
 
+function generateData() {
+  const data: {
+    value: number
+    desc: string
+    disabled: boolean
+  }[] = []
+  for (let i = 1; i <= 15; i++) {
+    data.push({
+      value: i,
+      desc: `Option ${i}`,
+      disabled: i % 4 === 0
+    })
+  }
+  return data
+}
+
 const schema = reactive<VFormSchema[]>([
   {
     field: 'field1',
@@ -618,6 +634,82 @@ const schema = reactive<VFormSchema[]>([
       voidIcon: markRaw(ChatRound),
       icons: [markRaw(ChatRound), markRaw(ChatLineRound), markRaw(ChatDotRound)]
     }
+  },
+  {
+    field: 'field32',
+    label: t('formDemo.colorPicker'),
+    component: 'Divider'
+  },
+  {
+    field: 'field33',
+    label: t('formDemo.default'),
+    component: 'ColorPicker'
+  },
+  {
+    field: 'field34',
+    label: t('formDemo.transfer'),
+    component: 'Divider'
+  },
+  {
+    field: 'field35',
+    label: t('formDemo.default'),
+    component: 'Transfer',
+    componentProps: {
+      props: {
+        key: 'value',
+        label: 'desc',
+        disabled: 'disabled'
+      },
+      data: generateData()
+    },
+    value: [],
+    colProps: {
+      xl: 12
+    }
+  },
+  {
+    field: 'field36',
+    label: t('formDemo.slot'),
+    component: 'Transfer',
+    componentProps: {
+      props: {
+        key: 'value',
+        label: 'desc',
+        disabled: 'disabled'
+      },
+      leftDefaultChecked: [2, 3],
+      rightDefaultChecked: [1],
+      data: generateData(),
+      slots: {
+        default: true
+      }
+    },
+    value: [1],
+    colProps: {
+      xl: 12
+    }
+  },
+  {
+    field: 'field37',
+    label: `${t('formDemo.render')}`,
+    component: 'Transfer',
+    componentProps: {
+      props: {
+        key: 'value',
+        label: 'desc',
+        disabled: 'disabled'
+      },
+      leftDefaultChecked: [2, 3],
+      rightDefaultChecked: [1],
+      data: generateData(),
+      renderContent: (h: Fn, option: Recordable) => {
+        return h('span', null, `${option.value} - ${option.desc}`)
+      }
+    },
+    value: [1],
+    colProps: {
+      xl: 12
+    }
   }
 ])
 
@@ -679,6 +771,10 @@ setTimeout(() => {
         <span>{{ data.label }}</span>
         <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
       </template>
+
+      <template #field36-default="{ option }">
+        <span>{{ option.value }} - {{ option.desc }}</span>
+      </template>
     </VFrom>
   </ElConfigProvider>
 </template>

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

@@ -12,7 +12,6 @@ import {
   setModel
 } from './helper'
 import { useRenderSelect } from './components/useRenderSelect'
-import { useRenderCascader } from './components/useRenderCascader'
 
 export default defineComponent({
   name: 'VForm',
@@ -90,7 +89,13 @@ export default defineComponent({
     // 渲染formItem
     function renderFormItem(item: VFormSchema) {
       // 单独给只有options属性的组件做判断
-      const notRenderOptions = ['SelectV2', 'Cascader']
+      const notRenderOptions = ['SelectV2', 'Cascader', 'Transfer']
+      const slotsMap: Recordable = {
+        ...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
+      }
+      if (item?.component !== 'SelectV2' && item.options) {
+        slotsMap.default = () => renderOptions(item)
+      }
       return (
         <ElFormItem {...(item.formItemProps || {})} prop={item.field} label={item.label}>
           {() => {
@@ -99,20 +104,12 @@ export default defineComponent({
               <Com
                 vModel={formModel[item.field]}
                 {...(autoSetPlaceholder && setTextPlaceholder(item))}
-                {...setComponentProps(item.componentProps)}
-                options={
-                  notRenderOptions.includes(item?.component as string)
-                    ? item.options || []
-                    : undefined
-                }
+                {...setComponentProps(item)}
+                {...(notRenderOptions.includes(item?.component as string) && item.options
+                  ? { options: item.options || [] }
+                  : {})}
               >
-                {{
-                  default: (data: Recordable) =>
-                    item.options && item?.component !== 'SelectV2'
-                      ? renderOptions(item, data)
-                      : undefined,
-                  ...setItemComponentSlots(slots, item?.componentProps?.slots, item.field)
-                }}
+                {{ ...slotsMap }}
               </Com>
             )
           }}
@@ -121,14 +118,11 @@ export default defineComponent({
     }
 
     // 渲染options
-    function renderOptions(item: VFormSchema, data: Recordable) {
+    function renderOptions(item: VFormSchema) {
       switch (item.component) {
         case 'Select':
           const { renderSelectOptions } = useRenderSelect(slots)
           return renderSelectOptions(item)
-        case 'Cascader':
-          const { useRenderCascaderOptions } = useRenderCascader(slots)
-          return useRenderCascaderOptions(item, data)
         default:
           break
       }

+ 0 - 23
src/components/Form/src/components/useRenderCascader.tsx

@@ -1,23 +0,0 @@
-import { Slots } from 'vue'
-import { getSlot } from '@/utils/tsxHelper'
-
-// 这个可能是element-plus的BUG,需要这么处理,才能渲染出来。
-export function useRenderCascader(slots: Slots) {
-  function useRenderCascaderOptions(item: VFormSchema, data: Recordable) {
-    return (
-      <span>
-        {{
-          default: () => {
-            return item?.componentProps?.slots?.default
-              ? getSlot(slots, `${item.field}-default`, data)
-              : data?.data[item?.optionsField?.labelField || 'label']
-          }
-        }}
-      </span>
-    )
-  }
-
-  return {
-    useRenderCascaderOptions
-  }
-}

+ 9 - 6
src/components/Form/src/helper.ts

@@ -71,14 +71,17 @@ export function setGridProp(col: ColProps = {}): ColProps {
 
 /**
  *
- * @param props 传入的组件属性
+ * @param item 传入的组件属性
  * @returns 默认添加 clearable 属性
  */
-export function setComponentProps(props: Recordable = {}): Recordable {
-  const componentProps: Recordable = {
-    clearable: true,
-    ...props
-  }
+export function setComponentProps(item: VFormSchema): Recordable {
+  const notNeedClearable = ['ColorPicker']
+  const componentProps: Recordable = notNeedClearable.includes(item.component as string)
+    ? { ...item.componentProps }
+    : {
+        clearable: true,
+        ...item.componentProps
+      }
   // 需要删除额外的属性
   delete componentProps?.slots
   return componentProps

+ 4 - 1
src/locales/en.ts

@@ -20,6 +20,9 @@ export default {
     selectV2: 'SelectV2',
     cascader: 'Cascader',
     switch: 'Switch',
-    rate: 'Rate'
+    rate: 'Rate',
+    colorPicker: 'ColorPicker',
+    transfer: 'Transfer',
+    render: 'Render'
   }
 }

+ 4 - 1
src/locales/zh-CN.ts

@@ -20,6 +20,9 @@ export default {
     selectV2: '虚拟列表选择器',
     cascader: '级联选择器',
     switch: '开关',
-    rate: '评分'
+    rate: '评分',
+    colorPicker: '颜色选择器',
+    transfer: '穿梭框',
+    render: '渲染器'
   }
 }