> 表单组件

```vue
<def-form v-bind="form" :list="list" :data="data" @submit="onSubmit" @search="onSearch" />
```

```js
// 自定义校验规则
const validateAccount = (rule: any, value: any, callback: any) => {
  if (value.trim() === '') {
    callback(new Error('用户名不能为空'))
  } else if (value.trim().length < 3) {
    callback(new Error('长度不低于3位'))
  } else {
    callback()
  }
}
// form表单配置（可有可无）
const form: IForm = {
  inline: false,
  labelWidth: 120,
  size: 'large',
  labelSuffix: ':',
  layout: {
    xs: 24,
    sm: 24,
    md: 12,
    lg: 8,
    xl: 6,
    gutter: 50
  }
}
// form表单项配置
const selectData = ref<IChildrenData[]>([])
const radioData = ref<IChildrenData[]>([])
const checkboxData = ref<IChildrenData[]>([])
const cascaderData = ref<IChildrenData[]>([])
const uploadOptions: IUpload = {
  disabled: false,
  listType: 'picture-card',
  limit: 3,
  hiddenTip: false
}
const list = ref<IFormItem[]>([])
setTimeout(() => {
  selectData.value = [
    {
      label: '吃饭',
      value: 'eat'
    },
    {
      label: '睡觉',
      value: 'sleep'
    },
    {
      label: '学习',
      value: 'learn'
    }
  ]
  radioData.value = [
    {
      label: '单选1',
      value: '1'
    },
    {
      label: '单选2',
      value: '2'
    }
  ]
  checkboxData.value = [
    {
      label: '多选框1',
      value: '1'
    },
    {
      label: '多选框2',
      value: '2'
    }
  ]
  cascaderData.value = [
    {
      value: 'guide',
      label: 'Guide',
      children: [
        {
          value: 'disciplines',
          label: 'Disciplines',
          children: [
            {
              value: 'consistency',
              label: 'Consistency'
            },
            {
              value: 'feedback',
              label: 'Feedback'
            },
            {
              value: 'efficiency',
              label: 'Efficiency'
            },
            {
              value: 'controllability',
              label: 'Controllability'
            }
          ]
        },
        {
          value: 'navigation',
          label: 'Navigation',
          children: [
            {
              value: 'side nav',
              label: 'Side Navigation'
            },
            {
              value: 'top nav',
              label: 'Top Navigation'
            }
          ]
        }
      ]
    },
    {
      value: 'component',
      label: 'Component',
      children: [
        {
          value: 'basic',
          label: 'Basic',
          children: [
            {
              value: 'layout',
              label: 'Layout'
            },
            {
              value: 'color',
              label: 'Color'
            },
            {
              value: 'typography',
              label: 'Typography'
            },
            {
              value: 'icon',
              label: 'Icon'
            },
            {
              value: 'button',
              label: 'Button'
            }
          ]
        },
        {
          value: 'form',
          label: 'Form',
          children: [
            {
              value: 'radio',
              label: 'Radio'
            },
            {
              value: 'checkbox',
              label: 'Checkbox'
            },
            {
              value: 'input',
              label: 'Input'
            },
            {
              value: 'input-number',
              label: 'InputNumber'
            },
            {
              value: 'select',
              label: 'Select'
            },
            {
              value: 'cascader',
              label: 'Cascader'
            },
            {
              value: 'switch',
              label: 'Switch'
            },
            {
              value: 'slider',
              label: 'Slider'
            },
            {
              value: 'time-picker',
              label: 'TimePicker'
            },
            {
              value: 'date-picker',
              label: 'DatePicker'
            },
            {
              value: 'datetime-picker',
              label: 'DateTimePicker'
            },
            {
              value: 'upload',
              label: 'Upload'
            },
            {
              value: 'rate',
              label: 'Rate'
            },
            {
              value: 'form',
              label: 'Form'
            }
          ]
        }
      ]
    }
  ]
  list.value = [
    {
      element: 'el-input',
      prop: 'account',
      label: '用户名',
      value: '',
      rules: [
        // { required: true, message: '用户名不能为空', trigger: 'blur' },
        // { min: 3, message: '长度不低于3位', trigger: 'blur' },
        { validator: validateAccount, trigger: 'blur' }
      ],
      elementAttrs: {
        type: 'text',
        placeholder: '请输入账号',
        clearable: true
      }
    },
    {
      element: 'el-input',
      prop: 'password',
      label: '密码',
      value: '',
      rules: [
        { required: true, message: '密码不能为空', trigger: 'blur' },
        { min: 6, max: 15, message: '长度必须在6-15位', trigger: 'blur' }
      ],
      elementAttrs: {
        type: 'password',
        placeholder: '请输入密码',
        clearable: true,
        showPassword: true
      }
    },
    {
      element: 'el-select',
      label: '下拉框选择',
      prop: 'select',
      value: '',
      rules: [
        {
          required: true,
          message: '爱好不能为空',
          trigger: 'change'
        }
      ],
      elementAttrs: {
        placeholder: '请选择爱好',
        clearable: true
      },
      subElement: 'el-option',
      children: selectData.value
    },
    {
      element: 'el-date-picker',
      prop: 'date',
      label: '日期选择',
      value: '',
      rules: {
        required: true,
        message: '日期不能为空',
        trigger: 'change'
      },
      elementAttrs: {
        placeholder: '请选择日期',
        format: 'YYYY-MM-DD',
        valueFormat: 'YYYY-MM-DD'
      }
    },
    {
      element: 'el-time-picker',
      prop: 'time',
      label: '时间选择',
      value: '',
      rules: {
        required: true,
        message: '时间不能为空',
        trigger: 'change'
      },
      elementAttrs: {
        placeholder: '请选择时间',
        format: 'hh:mm:ss',
        valueFormat: 'h:m:s'
      }
    },
    {
      element: 'el-switch',
      prop: 'switch',
      label: '开关',
      value: false
    },
    {
      element: 'el-radio-group',
      prop: 'radio',
      label: '单选框',
      value: '',
      rules: {
        required: true,
        message: '单选框不能为空',
        trigger: 'change'
      },
      subElement: 'el-radio',
      children: radioData.value
    },
    {
      element: 'el-checkbox-group',
      prop: 'checkbox',
      label: '多选框',
      value: [],
      rules: {
        required: true,
        message: '多选框不能为空',
        trigger: 'change'
      },
      subElement: 'el-checkbox',
      children: checkboxData.value
    },
    {
      element: 'el-color-picker',
      prop: 'color',
      label: '颜色选择',
      value: '',
      rules: [{ required: true, message: '请选择一个颜色', trigger: 'change' }]
    },
    {
      element: 'el-input-number',
      prop: 'number',
      label: '数字选择',
      value: 0
    },
    {
      element: 'el-rate',
      prop: 'rate',
      label: '评分',
      value: 0
    },
    {
      element: 'el-slider',
      prop: 'slider',
      label: '滑块',
      value: 0
    },
    {
      element: 'el-cascader',
      prop: 'cascader',
      label: '级联选择器',
      value: '',
      children: cascaderData.value
    },
    {
      element: 'def-icon-picker',
      prop: 'iconPicker',
      label: '图标选择器',
      value: ''
    },
    {
      element: 'def-region-picker',
      prop: 'regionPicker',
      label: '行政区选择器',
      value: '',
      elementAttrs: {
        label: 'name',
        value: 'code'
      }
    },
    {
      element: 'def-upload',
      prop: 'upload',
      label: '上传',
      value: [],
      layout: {
        xs: 24,
        sm: 24,
        md: 24,
        lg: 12,
        xl: 12
      },
      elementAttrs: {
        ...uploadOptions,
        style: {
          width: '100%',
          height: '150px'
        }
      }
    },
    {
      element: 'el-input',
      prop: 'textarea',
      label: '文本域',
      value: '',
      elementAttrs: {
        type: 'textarea',
        placeholder: '请输入文本'
      },
      layout: {
        xs: 24,
        sm: 24,
        md: 24,
        lg: 24,
        xl: 24
      },
      style: {
        height: '300px',
        width: '100%'
      }
    },
    {
      element: 'def-editor',
      prop: 'editor',
      label: '富文本编辑器',
      value: '',
      layout: {
        xs: 24,
        sm: 24,
        md: 24,
        lg: 24,
        xl: 24
      },
      elementAttrs: {
        style: {
          height: '600px'
        }
      }
    },
    {
      element: 'el-button',
      prop: '',
      label: '',
      value: '',
      layout: {
        xs: 24,
        sm: 24,
        md: 24,
        lg: 24,
        xl: 24
      },
      style: {
        justifyContent: 'flex-end'
      },
      action: [
        {
          label: '确认',
          type: 'primary',
          event: 'submit',
          size: 'large',
          icon: 'CircleCheck',
          iconSize: 16
        },
        {
          label: '查询',
          type: 'success',
          event: 'search',
          icon: 'Search'
        },
        {
          label: '重置',
          event: 'reset',
          type: 'warning',
          icon: 'RefreshRight'
        },
        {
          label: '清空',
          event: 'clear',
          type: 'danger',
          icon: 'CircleClose'
        }
      ]
    }
  ]
}, 1000)
// 数据回显处理
const data = ref<any>(null)
const handleFormData = () => {
  const obj: any = {
    account: '123',
    password: 'dfc123',
    select: 'sleep',
    date: '2022-06-20',
    time: '3:43:43',
    switch: false,
    radio: '2',
    checkbox: ['1', '2'],
    color: '#123456',
    number: 6,
    rate: 3,
    slider: 66,
    cascader: 'feedback',
    iconPicker: 'check',
    regionPicker: ['110000', '110100', '110102'],
    upload: [],
    textarea: '666',
    editor: '<p>333</p>'
  }
  data.value = obj
}
handleFormData()
// 提交
const onSubmit = (model: any) => {
  console.log('父组件拿到数据-submit', model)
  if (model) {
    // ElMessage.success('操作成功')
  } else {
    // ElMessage.error('表单输入不完整')
  }
}
// 查询
const onSearch = (model: any) => {
  console.log('父组件拿到数据-search', model)
}
```
