npm package: @gx-web/ep-comp
Description: 冠宣element-plus组件库
Author: wangjiahui
Latest version: 1.0.0

# EP-Comp 组件库

基于 Element Plus 的高级组件库，提供更便捷的表单构建和组件管理功能。

## 特性

- 🎯 **声明式表单**：通过配置快速构建表单
- 📱 **响应式栅格**：支持灵活的栅格布局
- ⚡ **异步渲染**：支持自定义渲染函数
- 🔧 **组件映射**：灵活的组件注册和管理
- 🎨 **类型安全**：完整的 TypeScript 支持

## 安装

```bash
npm install @gx-web/ep-comp
```

## 基础用法

### 1. 基础表单

```vue
<template>
  <GXForm
    v-model="formData"
    :items="formItems"
    label-width="120px"
    @submit="handleSubmit"
    @reset="handleReset"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { GXForm } from '@gx-web/ep-comp'
import type { EPFormItemConfigType } from '@gx-web/ep-comp'

const formData = ref({
  username: '',
  email: '',
  age: 18
})

const formItems: EPFormItemConfigType<any>[] = [
  {
    prop: 'username',
    label: '用户名',
    type: 'input',
    required: true,
    props: {
      placeholder: '请输入用户名'
    }
  },
  {
    prop: 'email',
    label: '邮箱',
    type: 'input',
    required: true,
    props: {
      placeholder: '请输入邮箱',
      type: 'email'
    }
  },
  {
    prop: 'age',
    label: '年龄',
    type: 'number',
    props: {
      min: 0,
      max: 120
    }
  }
]

const handleSubmit = (data: any) => {
  console.log('表单提交:', data)
}

const handleReset = () => {
  console.log('表单重置')
}
</script>
```

### 2. 栅格布局表单

```vue
<template>
  <GXForm
    v-model="formData"
    :items="formItems"
    label-width="120px"
    :gutter="20"
    @submit="handleSubmit"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { GXForm } from '@gx-web/ep-comp'
import type { EPFormItemConfigType } from '@gx-web/ep-comp'

const formData = ref({
  name: '',
  phone: '',
  address: '',
  city: '',
  zipCode: '',
  country: ''
})

const formItems: EPFormItemConfigType<any>[] = [
  {
    prop: 'name',
    label: '姓名',
    type: 'input',
    required: true,
    col: { span: 12 }, // 占据12列（24栅格系统的一半）
    props: {
      placeholder: '请输入姓名'
    }
  },
  {
    prop: 'phone',
    label: '电话',
    type: 'input',
    col: { span: 12 }, // 占据12列
    props: {
      placeholder: '请输入电话'
    }
  },
  {
    prop: 'address',
    label: '地址',
    type: 'input',
    col: { span: 24 }, // 占据整行
    props: {
      placeholder: '请输入详细地址'
    }
  },
  {
    prop: 'city',
    label: '城市',
    type: 'input',
    col: { span: 8 }, // 占据8列
    props: {
      placeholder: '请输入城市'
    }
  },
  {
    prop: 'zipCode',
    label: '邮编',
    type: 'input',
    col: { span: 8 }, // 占据8列
    props: {
      placeholder: '请输入邮编'
    }
  },
  {
    prop: 'country',
    label: '国家',
    type: 'select',
    col: { span: 8 }, // 占据8列
    props: {
      placeholder: '请选择国家',
      options: [
        { label: '中国', value: 'china' },
        { label: '美国', value: 'usa' },
        { label: '日本', value: 'japan' }
      ]
    }
  }
]
</script>
```

### 3. 异步渲染表单

```vue
<template>
  <GXForm v-model="formData" :items="formItems" label-width="120px" @submit="handleSubmit" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { GXForm } from '@gx-web/ep-comp'
import type { EPFormItemConfigType } from '@gx-web/ep-comp'

const formData = ref({
  title: '',
  content: '',
  tags: []
})

const formItems: EPFormItemConfigType<any>[] = [
  {
    prop: 'title',
    label: '标题',
    type: 'input',
    required: true,
    props: {
      placeholder: '请输入标题'
    }
  },
  {
    prop: 'content',
    label: '内容',
    render: (form) => {
      return {
        template: `
          <el-input
            v-model="content"
            type="textarea"
            :rows="4"
            placeholder="请输入内容"
            @input="updateContent"
          />
        `,
        setup() {
          const content = ref(form.content || '')

          const updateContent = (value: string) => {
            content.value = value
            form.content = value
          }

          return {
            content,
            updateContent
          }
        }
      }
    }
  },
  {
    prop: 'tags',
    label: '标签',
    render: (form) => {
      return {
        template: `
          <el-checkbox-group v-model="tags" @change="updateTags">
            <el-checkbox label="vue">Vue</el-checkbox>
            <el-checkbox label="react">React</el-checkbox>
            <el-checkbox label="angular">Angular</el-checkbox>
          </el-checkbox-group>
        `,
        setup() {
          const tags = ref(form.tags || [])

          const updateTags = (value: string[]) => {
            tags.value = value
            form.tags = value
          }

          return {
            tags,
            updateTags
          }
        }
      }
    }
  }
]
</script>
```

## 组件映射

### 注册自定义组件

```typescript
import { useComponentMap, registerGlobalComponent } from '@gx-web/ep-comp'
import MyCustomInput from './MyCustomInput.vue'

// 全局注册
registerGlobalComponent('customInput', MyCustomInput)

// 局部注册
const { registerComponent } = useComponentMap()
registerComponent('customInput', MyCustomInput)
```

### 使用自定义组件

```typescript
const formItems: EPFormItemConfigType<any>[] = [
  {
    prop: 'customField',
    label: '自定义字段',
    type: 'customInput', // 使用注册的自定义组件
    props: {
      placeholder: '自定义输入框'
    }
  }
]
```

## API 参考

### GXForm Props

| 参数       | 说明             | 类型                                                                                  | 默认值    |
| ---------- | ---------------- | ------------------------------------------------------------------------------------- | --------- |
| modelValue | 表单数据         | `any`                                                                                 | -         |
| items      | 表单项配置       | `EPFormItemConfigType[]`                                                              | -         |
| loading    | 提交按钮加载状态 | `boolean`                                                                             | `false`   |
| labelWidth | 标签宽度         | `string \| number`                                                                    | -         |
| inline     | 行内表单模式     | `boolean`                                                                             | `false`   |
| gutter     | 栅格间隔         | `number`                                                                              | `15`      |
| justify    | 水平排列方式     | `'start' \| 'end' \| 'center' \| 'space-around' \| 'space-between' \| 'space-evenly'` | `'start'` |
| align      | 垂直排列方式     | `'top' \| 'middle' \| 'bottom'`                                                       | -         |
| tag        | 自定义元素标签   | `string`                                                                              | `'div'`   |

### GXForm Events

| 事件名            | 说明               | 回调参数          |
| ----------------- | ------------------ | ----------------- |
| update:modelValue | 表单数据更新时触发 | `(value: any)`    |
| submit            | 表单提交时触发     | `(formData: any)` |
| reset             | 表单重置时触发     | -                 |

### EPFormItemConfigType

| 属性     | 说明           | 类型                                  | 默认值 |
| -------- | -------------- | ------------------------------------- | ------ |
| type     | 组件类型       | `ComponentKeyType`                    | -      |
| props    | 组件属性       | `ComponentPropsMap[ComponentKeyType]` | -      |
| prop     | 字段名         | `string`                              | -      |
| label    | 标签文本       | `string`                              | -      |
| required | 是否必填       | `boolean`                             | -      |
| rules    | 验证规则       | `RuleItem[]`                          | -      |
| hide     | 是否隐藏       | `boolean \| (form: T) => boolean`     | -      |
| col      | 栅格配置       | `ColConfigType`                       | -      |
| render   | 自定义渲染函数 | `(form: T) => Component`              | -      |

### ColConfigType

| 属性   | 说明                 | 类型                           | 默认值 |
| ------ | -------------------- | ------------------------------ | ------ |
| span   | 栅格占据的列数       | `number`                       | `24`   |
| offset | 栅格左侧的间隔格数   | `number`                       | `0`    |
| push   | 栅格向右移动的列数   | `number`                       | `0`    |
| pull   | 栅格向左移动的列数   | `number`                       | `0`    |
| xs     | `<768px` 响应式栅格  | `number \| MediaColConfigType` | -      |
| sm     | `≥768px` 响应式栅格  | `number \| MediaColConfigType` | -      |
| md     | `≥992px` 响应式栅格  | `number \| MediaColConfigType` | -      |
| lg     | `≥1200px` 响应式栅格 | `number \| MediaColConfigType` | -      |
| xl     | `≥1920px` 响应式栅格 | `number \| MediaColConfigType` | -      |

## 支持的组件类型

- `input` - 输入框
- `select` - 选择器
- `datePicker` - 日期选择器
- `switch` - 开关
- `checkbox` - 复选框
- `radio` - 单选框
- `textarea` - 文本域
- `number` - 数字输入框
- `timePicker` - 时间选择器
- `cascader` - 级联选择器
- `upload` - 上传
- `slider` - 滑块
- `rate` - 评分
- `colorPicker` - 颜色选择器

## 开发

```bash
# 安装依赖
pnpm install

# 运行测试
pnpm test

# 构建
pnpm build
```

## 许可证

MIT