# antd-table

二次封装表格

# Feature

## 可进行全局配置对话框相关属性，统一把控

\-

## 样式调整

- 调整了单元格左右 padding 加大，看着更加协调
- 调整了单元格内部的 ant-btn-link 按钮间距
- 可全局配置表格的 head ，body 单元格水平对齐，默认列头强制居中，表格 body 单元格 left 对齐

  head 单元格如果需要个别不居中，可以使用 table [customHeaderCell](https://next.antdv.com/components/table-cn#Column) 方式自定义

  ```js
  {
    title: '操作',
    dataIndex: 'action',
    customHeaderCell(column: any) {
      return {
        class: 'text-left' // or 'text-right'
      };
    }
  }
  ```

  body 单元格如果需要个别对齐方式不一致，可以使用 antd 自带配置风格

  ```js
  {
    title: '操作',
    dataIndex: 'action',
    align:'center' // or right
  }
  ```

- loading 展示的时候不显示空状态，antd 默认下都会一起显示看起来不协调

- 重写了 sorter 的上下箭头图片，[蓝湖参考](https://lanhuapp.com/web/#/item/project/detailDetach?tid=3e189f00-e766-420d-a5d1-e963c303b08c&pid=bd06380a-47e4-4580-a1f2-5ddc62bbd6b1&project_id=bd06380a-47e4-4580-a1f2-5ddc62bbd6b1&image_id=ac0dd0ac-23e3-48ad-a8d4-8277ddfa4fc3&fromEditor=true)

## 与 TableLayout 配合

- 当 TableLayout 出现 drawer 时，如果是对某一确认数据行操作，则表格对应行高亮且滚动到合适区域，如果是新增或其他，则左侧无可操作区域。

- 需要确保 a-table 都必须要 row-key 属性，否则不会高亮当前操作行，[参考 row-key](https://www.antdv.com/components/table-cn#%E6%B3%A8%E6%84%8F)

## tableColumnsOperate（tco） 部件，用于扩展表格列的筛选以及排序

通过新增表格属性 table-columns-operate 对象，来激活这个功能。

激活之后，悬浮到表格表头所有单元格将会动态出现 icon，再次悬浮 icon 展示 popover，则可进行表格列的筛选以及排序。

保存之后，将会以这样子的格式存储到 localStorage（key 为 unity-tco）：

```js
[
  {
    lotId: '10086', // 车场 id
    table: [
      {
        name: 'foo', // 表格名称，唯一
        value: [
          {
            dataIndex: 'id',
            visible: 1
          },
          {
            dataIndex: 'user,name',
            visible: 1
          },
          {
            dataIndex: 'url',
            visible: 1
          },
          {
            dataIndex: 'title',
            visible: 1
          },
          {
            dataIndex: 'action',
            visible: 1
          }
        ]
      }
    ]
  }
];
```

> tips：不要对复杂表头开启这个功能

✨ 使用 JSON-Schema 的工具 [ajv](https://github.com/ajv-validator/ajv)，[ajv-keywords](https://github.com/epoberezkin/ajv-keywords) 来验证本地存储数据格式是否正确。如果本地存储的格式被手动修改，或者其他。导致不正确，将会被直接清空！

✨ 处理表格新增，修改，删除列与本地缓存的冲突比较，展示正确的表格列

### Usage

```ts

// 如果有需要使用被改变后的列来做某些事，可以定义 newColumns 在 postColumns 接收到最新的 columns 进行赋值
const newColumns = ref<any[]>([]);

<a-table
  rowKey="id"
  v-bind="VBind"
  v-on="VOn"
  :table-columns-operate="{
    excludeHead: ['id'],
    excludeTail: ['action'],
    lotId: '10086',
    tableName: 'foo',

    postColumns(columns: any[]) {
      newColumns.value = columns;
    }
  }"
>
  ...
</a-table>

// 场景：使用 newColumns 来进行一些遍历，如 summary，保证表格列顺序一致
<template #summary>
  <a-table-summary fixed="bottom">
    <a-table-summary-row>
      <a-table-summary-cell>xxx</a-table-summary-cell>
      <a-table-summary-cell
        v-for="item in newColumns"
        :key="item.dataIndex"
      >
        <div>
          {{ item.dataIndex }}
        </div>
      </a-table-summary-cell>
    </a-table-summary-row>
  </a-table-summary>
</template>
```

### API

Table tableColumnsOperate

| 参数         | 说明                                                                                                                                       | 类型                      | 默认值     |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | ---------- |
| excludeHead  | 排除不参与的头部列（一般为头部固定列，如：fixed: 'left'）                                                                                  | Array<string \| string[]> | []         |
| excludeTail  | 排除不参与的尾部列（一般为操作列），exclude 别名                                                                                           | Array<string \| string[]> | []         |
| initHidden   | 初始化时，表格不展示的列（对应操作列为未选中）                                                                                             | Array<string \| string[]> | []         |
| lotId        | 车场 Id，必填，唯一                                                                                                                        | string                    | -          |
| tableName    | tableName，必填，唯一                                                                                                                      | string                    | -          |
| popoverTitle | popover 的 title                                                                                                                           | string                    | 报表列筛选 |
| postColumns  | 返回被改变之后的全新 columns，在初始化的时候就会触发返回<br>不要在拿这里返回的 columns 赋值给 tableOptions.columns，否则会导致死循环！！！ | (columns: any[])=>void    | -          |

# Usage

## 场景：表格操作列的 `Button` 为 `Dropdown`

```html
<script lang="ts" setup>
  // ...
  const drawer = reactive({
    visible: false
  });

  const myTable = ref();

  const tableProps = reactive({
    visibleAction: 'last' as string | number | null,
    visibleButton: 0 as number | null
  });

  const handleDDOperate = (id: string | number) => {
    drawer.visible = true;
    // 如果要显示 DropDown，对应索引 2
    tableProps.visibleButton = 2;
    // 主动调用方法高亮表格行
    myTable.value?.highlightRow(id);
  };
  // ...
</script>

<template>
  <tl v-model:drawer="drawer.visible">
    <tl-main>
      <tl-filter>
        <!-- ... -->
      </tl-filter>

      <tl-table
        :visibleAction="tableProps.visibleAction"
        :visibleButton="tableProps.visibleButton"
      >
        <a-table ref="myTable" rowKey="id">
          <template #bodyCell="{ text, column, record }">
            <template v-if="column.dataIndex === 'name'">
              <!-- ... -->
            </template>

            <template v-else-if="column.dataIndex === 'action'">
              <a-button type="link">编辑</a-button>
              <a-button type="link" danger>删除</a-button>
              <a-dropdown>
                <!-- ⚠️ ⚠️ ⚠️ dropdown 要设置为 link button，和其他 button 样式统一 -->
                <a-button type="link">
                  dropdown
                  <DownOutlined />
                </a-button>

                <template #overlay>
                  <a-menu>
                    <a-menu-item @click="handleDDOperate(record.id)">
                      操作1
                    </a-menu-item>
                    <a-menu-item @click="handleDDOperate(record.id)">
                      操作2
                    </a-menu-item>
                  </a-menu>
                </template>
              </a-dropdown>
            </template>
          </template>
        </a-table>
      </tl-table>
    </tl-main>

    <tl-drawer>
      <!-- ... -->
    </tl-drawer>
  </tl>
</template>
```

# API

## Exposes

| 名称         | 说明                                                                                                                                                                                                                                                                   | 类型                               |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| highlightRow | 外部主动控制行是否高亮 & 当前行移动到可视范围<br>（一般 `Button` 不需要主动调用就能高亮，是因为内部做了处理，判断当前点击的按钮处于哪行，但是 `Dropdown` 的下拉框是脱离 `table` 的，所以 `Dropdown` 的 `item` 被点击，内部无法判断点击了哪行，需要主动调用方法来高亮） | (rowKey: string \| number) => void |
|              |
