# VTable 组件 API 文档

## 组件简介 | Component Introduction
`VTable` 是基于 Element Plus 的表格组件，支持分页、插槽自定义、方法暴露等。

`VTable` is a table component based on Element Plus, supporting pagination, custom slots, and exposed methods.

---

## Props/属性
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 |
|--------|------|------|----------|--------|
| columns | 列配置 | Array | 是 | - |
| data | 表格数据 | Array | 是 | - |
| config | 表格配置对象 | Object | 否 | {} |
| pageConfig | 分页配置对象 | Object/Boolean | 否 | {} |
| total | 总条数 | Number | 否 | 0 |
| loading | 加载状态 | Boolean/Object | 否 | false |

---

## columns 配置项 | Columns Options
每一项对应一列，支持以下字段：

| 字段名 | 说明 | 类型 | 备注 |
|--------|------|------|------|
| type | 列类型 | String | 'selection'（多选框）、'index'（序号）、'expand'（展开）、'default'（常规）|
| key | 数据字段名 | String | 用于数据绑定 |
| title | 列标题 | String/Function | 支持字符串或函数返回VNode |
| slot | 插槽名 | String/Object | 支持自定义单元格/表头插槽，如 { default, header } |
| render | 自定义渲染函数 | Function | (scope, emit) => VNode |
| children | 嵌套子列 | Array | 用于多级表头 |
| width | 列宽 | Number/String |  |
| minWidth | 最小宽度 | Number/String |  |
| index | 自定义序号方法 | Function | type='index' 时生效 |
| formatter | 格式化函数 | Function | (row, column, cellValue, index) => any |
| showOverflowTooltip | 超出省略提示 | Boolean |  |
| fixed | 固定列 | Boolean/String | true/'left'/'right' |
| align | 对齐方式 | String | 'left'/'center'/'right' |
| ... | 其余 el-table-column 支持的属性 |  |  |

---

## config 配置项 | Config Options
表格整体配置，支持以下字段：

| 字段名 | 说明 | 类型 | 备注 |
|--------|------|------|------|
| border | 是否显示边框 | Boolean |  |
| stripe | 斑马纹 | Boolean |  |
| rowKey | 行数据唯一标识 | String |  |
| highlightCurrentRow | 高亮当前行 | Boolean |  |
| maxHeight | 最大高度 | Number/String |  |
| tableLayout | 表格布局 | String | 'auto'/'fixed' |
| rowClassName | 行 class 名 | String/Function | (row, rowIndex) => string |
| class | 表格 class | String |  |
| style | 表格 style | Object |  |
| lazy | 懒加载 | Boolean |  |
| load | 懒加载方法 | Function | (row, treeNode, resolve) => void |
| defaultSort | 默认排序 | Object | { prop, order } |
| slot | 插槽名映射 | Object | { empty, append } |
| ... | 其余 el-table 支持的属性 |  |  |

---

## pageConfig 配置项 | PageConfig Options
分页配置，支持以下字段：

| 字段名 | 说明 | 类型 | 备注 |
|--------|------|------|------|
| layout | 分页布局 | String | 参考 el-pagination，默认 'slot,total,prev,pager,next,sizes' |
| align | 分页对齐 | String | 'left'/'center'/'right' |
| defaultPageSize | 默认每页条数 | Number |  |
| background | 背景 | Boolean |  |
| small | 小型分页 | Boolean |  |
| disabled | 禁用 | Boolean |  |
| onSizeChange | pageSize 改变回调 | Function | (size) => void |
| onCurrentChange | 当前页改变回调 | Function | (page) => void |
| slot | 分页插槽名 | String |  |
| class | 分页 class | String |  |
| ... | 其余 el-pagination 支持的属性 |  |  |

---

## v-model
- pageSize: 每页条数，类型：`Number`
- currentPage: 当前页码，类型：`Number`

---

## 方法 | Methods (通过 ref 调用)
| 方法名 | 说明 |
|--------|------|
| refs.table | el-table 实例 |
| refs.page | el-pagination 实例 |
| clearSelection() | 清空选中项 |
| getSelectionRows() | 获取选中行 |
| toggleRowSelection(row, selected) | 切换某行选中状态 |
| toggleAllSelection() | 切换全选 |
| toggleRowExpansion(row, expanded) | 切换行展开 |
| setCurrentRow(row) | 设置当前行 |
| clearSort() | 清除排序 |
| clearFilter(columnKey) | 清除筛选 |
| doLayout() | 重新布局 |
| sort(prop, order) | 排序 |
| scrollTo(position) | 滚动到指定位置 |
| setScrollTop(top) | 设置滚动条顶部位置 |
| setScrollLeft(left) | 设置滚动条左侧位置 |

---

## 插槽 | Slots
- 支持通过 slot 名自定义表格内容、表头、空数据、分页等。
- columns/children/slot 字段可实现多级表头和自定义单元格。

---

## 示例 | Example
```vue
<template>
  <VTable
    ref="tableRef"
    :columns="columns"
    :data="tableData"
    :config="config"
    :page-config="paginationConfig"
    :total="total"
    :loading="loading"
    v-model:page-size="pageSize"
    v-model:current-page="currentPage"
  >
    <template #expandSlot="scope">
      <div>
        <p>Address: {{ scope.row.address }}</p>
        <p>Name: {{ scope.row.name }}</p>
      </div>
    </template>
    <template #addressSlot="scope">
      <el-input v-model="scope.row.address"></el-input>
    </template>
    <template #startDateHeader>
      <el-input v-model="search" size="small" placeholder="Type to search" />
    </template>
    <template #startDate="{ row, column, $index }">{{ row.startDate }}--{{ $index }}</template>
    <template #emptySlot>自定义的数据为空</template>
    <template #pageSlot>这是page的是slot</template>
  </VTable>
</template>

<script setup>
import { ref, h } from 'vue'
import { VTable } from 'your-lib-path'
import { ElInput, ElInputNumber } from 'element-plus'

const columns = [
  { type: 'selection', width: 50 },
  { title: '序号', type: 'index', width: 40, index: (i) => i + 1 },
  {
    title: '基本信息',
    children: [
      {
        slot: { default: 'startDate', header: 'startDateHeader' },
        minWidth: 200,
        title: '开始时间'
      },
      {
        slot: 'endDate',
        title: '结束时间',
        minWidth: 200
      }
    ]
  },
  {
    key: 'name',
    title: '姓名',
    minWidth: 150,
    render({ row, column, rowIndex }) {
      return h(ElInput, {
        type: 'text',
        modelValue: row.name,
        onChange: (val) => row.name = val
      })
    }
  },
  {
    title: '年龄',
    key: 'age',
    minWidth: 130,
    render({ row, column, rowIndex }) {
      return h(ElInputNumber, {
        modelValue: row.age,
        onChange: (val) => row.age = val
      })
    }
  },
  {
    title: '性别',
    minWidth: 100,
    slot: 'gender'
  },
  {
    key: 'address',
    title: '地址',
    slot: 'addressSlot',
    minWidth: 200
  }
]

const config = {
  border: false,
  class: 'table-demo',
  style: {},
  rowKey: 'name',
  lazy: true,
  load(row, treeNode, resolve) {
    setTimeout(() => resolve([]), 1000)
  },
  highlightCurrentRow: true,
  maxHeight: 500,
  tableLayout: 'auto',
  rowClassName: ({ row, rowIndex }) => rowIndex % 2 ? 'odd-row' : '',
  slot: { empty: 'emptySlot' }
}

const paginationConfig = {
  background: true,
  defaultPageSize: 30,
  onSizeChange(size) { console.log('sizeChange', size) },
  class: 'page-test',
  slot: 'pageSlot'
}

const tableData = ref([])
const total = ref(0)
const pageSize = ref(10)
const currentPage = ref(1)
const search = ref('')
const loading = ref(false)
</script> 