# CustomizeForm(待优化)

## CustomizeForm 属性 (Props)

|     参数      |                     说明                     |             类型              |  默认值   | 必填 |
| :-----------: | :------------------------------------------: | :---------------------------: | :-------: | :--: |
|    config     |                  表单配置项                  |         IFormConfig[]         |    []     |  ✓   |
|  modelValue   |                 表单数据对象                 |    Record<string, unknown>    |    {}     |  ✕   |
|  labelWidth   |                 表单标签宽度                 |        string \|number        |    100    |  ✕   |
| formItemWidth |                  表单项宽度                  |        string \|number        |    50%    |  ✕   |
|     size      |                   组件尺寸                   | 'large'\| 'default'\| 'small' | 'default' |  ✕   |
|    inline     |                 是否行内布局                 |            boolean            |   false   |  ✕   |
| labelPosition |                   标签位置                   |   'left'\| 'right'\| 'top'    |  'right'  |  ✕   |
|      ...      | 其余属性与 element-plus 文档中 Form API 相同 |              ...              |    ...    | ...  |

- **CustomizeForm 说明**:
- CustomizeForm 属性 (Props) 可自行添加，添加属性与 element-plus 文档中 form Props 相同
- 可参考文件 src\views\logistics\logisticsMethod.vue

---

### IFormConfig 配置项

|     属性      |                           说明                           |                 类型                  | 默认值 |
| :-----------: | :------------------------------------------------------: | :-----------------------------------: | :----: |
|     prop      |                        表单字段名                        |                string                 |   -    |
|     label     |                         表单标签                         |                string                 |   -    |
|     title     |                         分组标题                         |                string                 |   -    |
|     type      |                         控件类型                         |                string                 |   -    |
|     attrs     |                       控件属性配置                       |            SimpleFormData             |   -    |
|     rules     |                         验证规则                         |     FormItemRule\| FormItemRule[]     |   -    |
|    render     |                      自定义渲染函数                      | () => VNode \| VNode[] \| JSX.Element |   -    |
|      btn      |                         操作按钮                         |   JSX.Element \|(() => JSX.Element)   |   -    |
| isIncludeProp | 是否包含在 prop 属性中， 需搭配 refashConfig（）方法使用 |                boolean                |   -    |
|     fixed     |                         固定位置                         |                string                 |   -    |

- attrs 中 element-plus 文档中 FormItem API 相同
- 可参考文件 src\views\logistics\declarationRule.vue

---

### 控件类型 (SimpleFormData)

|     类型值      |    对应组件     |      说明      |
| :-------------: | :-------------: | :------------: |
|      input      |     ElInput     |   普通输入框   |
|   amountInput   |   AmountInput   |   金额输入框   |
| dateRangePicker | DateRangePicker | 日期范围选择器 |
|   datePicker    |   DatePicker    |   日期选择器   |
|     select      |     Select      |   下拉选择框   |
|     switch      |     Switch      |    开关组件    |

- form 表格如需动态渲染则需要传入计算属性 config

```tsx **config 示例**
const editForm = ref({})
const config = [
  //含有title属性的对象独占一行，目前最好只做标题使用，也可以用render自定义内容但是可能有bug待优化
  {
    title: '个人信息',
    render: () => VNode,
  },
  {
    prop: 'name',
    label: '姓名',
    type: 'input',
    attrs: {
      placeholder: '请输入姓名',
      clearable: true,
    },
    rules: { required: true, message: '姓名不能为空' },
  },
  {
    prop: 'birthday',
    label: '出生日期',
    type: 'datePicker',
    attrs: {
      format: 'YYYY-MM-DD',
      valueFormat: 'YYYY-MM-DD',
      placeholder: '选择出生日期',
    },
  },
  {
    prop: 'gender',
    label: '性别',
    type: 'select',
    attrs: {
      options: [
        { label: '男', value: 1 },
        { label: '女', value: 2 },
        { label: '其他', value: 3 },
      ],
    },
  },
  {
    title: '联系信息',
  },
  {
    prop: 'salary',
    label: '期望薪资',
    type: 'amountInput',
    attrs: {
      min: 0,
      max: 100000,
      precision: 0,
      step: 1000,
      controlsPosition: 'right',
      //appendRender：   amountInput组件插槽用法，需注意不可以直接使用v-model绑定
      appendRender: () => {
        return h(
          ElSelect,
          {
            modelValue: editForm.value['unit'],
            'onUpdate:modelValue': (val) => (editForm.value['unit'] = val),
            disabled: editForm.value['id'] ? true : false,
            placeholder: 'Select',
            style: { width: '115px' },
          },
          () => [
            h(ElOption, { label: 'oz', value: 'oz' }),
            h(ElOption, { label: 'LB', value: 'LB' }),
          ],
        )
      },
    },
  },
  {
    prop: 'agree',
    label: '用户协议',
    type: 'switch',
  },
]
```

---

## 事件 (Events)

|      事件名       |     说明     |       回调参数       |
| :---------------: | :----------: | :------------------: |
| update:modelValue | 表单数据更新 | 更新后的表单数据对象 |

---

## 可用方法

|    方法名     |                      说明                      |         参数          |
| :-----------: | :--------------------------------------------: | :-------------------: |
|   validate    |                    表单验证                    |          无           |
| clearValidate |                  清除验证信息                  |          无           |
|  resetFields  |                  重置表单字段                  |          无           |
| refashConfig  | 刷新表单配置，需要搭配 isIncludeProp 字段 使用 | showFields?: string[] |

- **说明**: 可新增方法自行添加
- showFields 字段是一个由 config 中 设置为 isIncludeProp：true 的对象值组成的数组。例如['prop1', 'prop2']

```vue
<template>
  <CustomizeForm ref="formRef" ... />
</template>

<script setup>
import { ref } from 'vue'

const formRef = ref()

// 验证表单
const validateForm = async () => {
  try {
    await formRef.value.validate()
    // 验证通过逻辑
  } catch (error) {
    // 验证失败处理
  }
}

// 重置表单
const resetForm = () => {
  formRef.value.resetFields()
}

// 刷新配置
const refreshFormConfig = () => {
  formRef.value.refashConfig(['prop1', 'prop2'])
}
</script>
```
