# antdv 中 table 组件

# 1. 介绍

ant-design-vue (4.1.2) 中的 table 组件

# 2. 注意

  1. 设置 resizable 时,需要留一列不设置 resizable,否则会造成拖拽异常
  2. 设置 width 时,需要留一列不设置 width,否则会造成表头与内容对不齐

# 3. 去掉分页器

示例:

<template>
  <a-table
    :pagination="false"
  >
  </a-table>
</template>

参考:

# 4. 列宽可拖拽调整

说明:

  1. 用于固定宽度的表格,列设置的宽度是 像素值
  2. 配合 ellipsis: true,表头、单元格 不会折行
  3. 至少需要一列(通常是最后一列) 不设置宽度且不可拖拽

代码:

<template>
  <a-table
    :columns="columns"
    @resizeColumn="handleResizeColumn"
  >
  </a-table>
</template>
<script>
export default {
  data() {
    return {
      columns: [
        { title: 'name', /* ... */ width: 200, ellipsis: true, resizable: true },
        { title: 'age', /* ... */ width: 200, ellipsis: true, resizable: true },
        { title: 'gender', /* ... */ ellipsis: true, resizable: false },
      ],
    };
  },

  methods: {
    handleResizeColumn(width, column) {
      column.width = width;
    },
  }
};
</script>

# 5. 单击选中行

<template>
  <a-table
    :data-source="list"
    :custom-row="customRow"
    :row-selection="rowSelection"
    rowKey="userId"
  >

  </a-table>
</template>
<script>
export default {
  data() {
    return {
      list: [
        { userId: '001', userName: 'zhangsan', /* ... */ },
        // ...
      ],

      rowSelection: {
        type: 'radio',
        selectedRowKeys: [],
        onChange: this.onSelectChange,
      },
    };
  },

  methods: {
    customRow(record, index) {
      return {
        onClick: () => {
          this.onClickRow(record);
        },
      };
    },

    onClickRow(record) {
      this.onSelectChange([record.userId], record);
    },

    onSelectChange(selectedRowKeys, record) {
      this.rowSelection.selectedRowKeys = selectedRowKeys;
    },
  },
};
</script>
<style>
/* 隐藏 radio 那列 */
.ant-table-selection-column {
  padding: 0!important;
}
.ant-table-selection-col {
  width: 0!important;
}
.ant-radio-wrapper {
  display: none;
}
</style>

# 6. 复选框和单选框的使用

说明:

  • 需要指定 record 中的主键名称
  • 无论是 checkbox 还是 radio,onChange 的方法签名不变

示例:

<template>
  <a-table
    row-key="userId"
    :data-source="list"
    :columns="columns"
    :row-selection="{ 
      type: 'checkbox',  /* 'checkbox' | 'radio' */
      columnWidth: 32, 
      selectedRowKeys, 
      onChange,
      getCheckboxProps,
    }"
  >
    ...
  </a-table>
</template>
<script>
export default {
  data() {
    return {
      selectedRowKeys: [],

      list: [
        { userId: '1', userName: 'zhangsan' },
      ]
    }
  },

  methods: {
    onChange(selectedRowKeys, selectedRows) {
      console.log(`selectedRowKeys: ${selectedRowKeys}`, 'selectedRows: ', selectedRows);
      this.selectedRowKeys = selectedRowKeys;
    },
    
    getCheckboxProps(record) {
      return {
        // 全部默认禁止选中
        // disabled: true,
        
        // 禁用某些记录
        disabled: record.status === 'disabled',
        
        // defaultChecked: record.state == 1,
      };
    }
  }
}
</script>

参考:

  • node_modules/ant-design-vue/es/table/interface.d.ts
  • node_modules/ant-design-vue/es/checkbox/interface.d.ts

# 7. 自定义渲染单元格

注意:

  • 使用 bodyCell 插槽的话,customRender 会被覆盖

示例:

<template>
  <a-table
    :columns="columns"
  >
    <template #bodyCell="{ column }">

      <!-- age 列上使用 customRender 不生效  -->
      <template v-if="column.key === 'age'">
        <CheckOutlined />
      </template>

    </template>
  </a-table>
</template>
<script lang="tsx">
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      columns: [
        // ...
        {
          title: 'Sheet Name',
          width: 100,
          dataIndex: 'sheetName',
          key: 'sheetName',
          
          /**
           * @param column - {title: 'Sheet Name', width: 100, dataIndex: 'sheetName', key: 'sheetName', customRender}
           */
          customRender({ text, record, index, column }) {
            /*
             处理 tsx 报错误的问题:
             
              tsconfig.json

                  "noImplicitAny": false,
             */
            return (
              <div>{ text }</div>
            );
          },
        },
      ]
    };
  },
});
</script>

# 8. 表头排序功能

<template>
  <a-table
    :columns="columns"
    :show-sorter-tooltip="false"
  />
</template>
<script lang="tsx">
import { defineComponent } from 'vue';

export default defineComponent({
  data() {
    return {
      columns: [
        // ...
        {
          title: 'Sheet Name',
          width: 100,
          dataIndex: 'sheetName',
          key: 'sheetName',
          
          sorter: (prevRecord, currRecord) => {
            const result = prevRecord.sheetName > prevRecord.sheetName

            return result ? 1 : -1;
          }
        },
      ]
    };
  },
});
</script>

# 9. 固定高度

说明:

  • 设置的高度不是 数据表格整体的高度,仅仅是 记录的容器的高度

示例:

<template>
  <a-table
    :scroll={ y: '200px' }
  >
  </a-table>
</template>

# 10. 排序

示例:

<template>
  <a-table
    :columns="columns"
    @change="handleChange"
  />
</template>
<script lang="ts">
import type { SorterResult } from 'ant-design-vue/es/table/interface';

export default {
  data() {
    return {
      columns: [
        { 
          title: 'Timestamp', 
          dataIndex: 'timeStamp', 
          key: 'timeStamp', 
          sorter: true, // 后台排序,侦听通过 change 事件
          defaultSortOrder: 'descend', // null | 'ascend' | 'descend'
        },
      ]
    }
  },
  
  methods: {
    handleChange(pagination, filters, sorter: SorterResult) {
      const {
        field, // timeStamp
        order, // 'descend' | 'ascend' | null;
      } = sorter;
    }
  }
}
</script>

# 11. 设置行的样式类

说明:

  • 额外添加 样式类名称

示例:

<template>
  <a-table
    :row-class-name="rowClassName"
  />
</template>
<script lang="ts">
import type { SorterResult } from 'ant-design-vue/es/table/interface';

export default {
  methods: {
    rowClassName({ __status }: IRecord, index) {
      if (__status === UploadStatus.Uploaded) {
        return 'lw-is-uploaded';
      }
      
      if (__status === UploadStatus.NotUploaded) {
        return 'lw-is-not-uploaded';
      }

      return '';
    },
  }
}
</script>

# 12. 设置单元格的样式

示例:

<template>
  <a-table
    :columns="columns"
  />
</template>
<script lang="ts">
export default {
  data() {
    return {
      columns: [
        { 
          title: 'Timestamp', 
          dataIndex: 'timeStamp', 
          key: 'timeStamp', 
          customCell: this.customCell,
        },
      ]
    }
  },
  
  methods: {
    customCell(record) {
      let className = '';

      if (record.xyz === 0 ) {
        className = 'lw-table-cell-danger';
      }

      return {
        class: className,
      }
    },
  }
}
</script>
本章目录