Skip to content

Vue 对齐方式

通过 alignvAlign 设置列的水平和垂直对齐方式。使用 headerAlignheaderVAlignfooterAlignfooterVAlign 分别覆盖表头和表尾的对齐。通过 cellStyle 可以为单个单元格独立设置对齐。

使用的 API

ts
type Column = {
  align: 'left' | 'center' | 'right';  // 列的水平对齐
  vAlign: 'top' | 'middle' | 'bottom';  // 列的垂直对齐
  headerAlign: 'left' | 'center' | 'right';  // 覆盖表头的水平对齐
  headerVAlign: 'top' | 'middle' | 'bottom';  // 覆盖表头的垂直对齐
  footerAlign: 'left' | 'center' | 'right';  // 覆盖表尾的水平对齐
  footerVAlign: 'top' | 'middle' | 'bottom';  // 覆盖表尾的垂直对齐
}

type Options = {
  align: 'left' | 'center' | 'right';  // 全局水平对齐
  vAlign: 'top' | 'middle' | 'bottom';  // 全局垂直对齐
  headerAlign: 'left' | 'center' | 'right';  // 全局表头水平对齐
  headerVAlign: 'top' | 'middle' | 'bottom';  // 全局表头垂直对齐
  footerAlign: 'left' | 'center' | 'right';  // 全局表尾水平对齐
  footerVAlign: 'top' | 'middle' | 'bottom';  // 全局表尾垂直对齐
  cellStyle: (column, row) => string;  // 单元格级别样式回调
}

优先级

column.headerAlign > column.align > options.headerAlign > options.align

示例

包含两个表格:列级对齐(headerAlign/footerAlign 覆盖 align)和单元格独立对齐(cellStyle 回调)。

微应用尚未挂载。

源码

点击查看源码
vue
<template>
  <div class="demo-wrapper">
    <h3 class="demo-title">Vue 对齐方式 — 列级对齐</h3>
    <div class="status-text">headerAlign/footerAlign 覆盖 align;headerVAlign/footerVAlign 覆盖 vAlign</div>
    <div style="width: 800px; height: 500px" class="demo-container">
      <VirtTableVue :columns="columns1" :options="options1" />
    </div>

    <h3 class="demo-title" style="margin-top: 32px;">Vue 对齐方式 — 单元格独立对齐</h3>
    <div class="status-text">通过 cellStyle 回调为每个单元格独立设置 align 和 vAlign</div>
    <div style="width: 800px; height: 340px" class="demo-container">
      <VirtTableVue :columns="columns2" :options="options2" />
    </div>
  </div>
</template>

<script setup lang="ts">
import { VirtTableVue, type VueTableColumn } from '@virt-table/vue';
import { faker } from '@faker-js/faker';

const columns1: VueTableColumn[] = [
  {
    key: 'col_0',
    title: 'headerAlign: center',
    width: 160,
    align: 'left',
    headerAlign: 'center',
    vAlign: 'top',
    headerVAlign: 'middle',
  },
  {
    key: 'col_1',
    title: 'footerAlign: right',
    width: 160,
    align: 'center',
    footerAlign: 'right',
    footerVAlign: 'bottom',
  },
  {
    key: 'col_2',
    title: 'align: right / vAlign: bottom',
    width: 180,
    align: 'right',
    vAlign: 'bottom',
  },
  {
    key: 'col_3',
    title: 'headerAlign: left',
    width: 160,
    align: 'center',
    headerAlign: 'left',
    headerVAlign: 'top',
  },
  {
    key: 'col_4',
    title: 'all center',
    width: 140,
    align: 'center',
    vAlign: 'middle',
    headerAlign: 'center',
    headerVAlign: 'middle',
    footerAlign: 'center',
    footerVAlign: 'middle',
  },
];

const ROW_COUNT = 200;

const list1 = Array.from({ length: ROW_COUNT }, (_, i) => {
  const row: Record<string, unknown> = { id: i };
  for (let c = 0; c < 5; c++) {
    row[`col_${c}`] = c === 0 ? faker.lorem.sentences(2) : `Row ${i} Col ${c}`;
  }
  return row;
});

const options1 = {
  list: list1,
  itemKey: 'id',
  estimatedSize: 40,
  buffer: 4,
  border: true,
  showFooter: true,
  footerData: [['Total', '100', '200', '300', 'Sum']],
};

const alignMap: Record<string, { align: string; vAlign: string }> = {
  '0,0': { align: 'left', vAlign: 'top' },
  '0,1': { align: 'center', vAlign: 'top' },
  '0,2': { align: 'right', vAlign: 'top' },
  '1,0': { align: 'left', vAlign: 'middle' },
  '1,1': { align: 'center', vAlign: 'middle' },
  '1,2': { align: 'right', vAlign: 'middle' },
  '2,0': { align: 'left', vAlign: 'bottom' },
  '2,1': { align: 'center', vAlign: 'bottom' },
  '2,2': { align: 'right', vAlign: 'bottom' },
};

const columns2: VueTableColumn[] = [
  { key: 'label', title: '行标签', width: 120 },
  { key: 'c0', title: 'left', width: 200 },
  { key: 'c1', title: 'center', width: 200 },
  { key: 'c2', title: 'right', width: 200 },
];

const list2 = [
  { id: 0, label: 'top', c0: 'left/top', c1: 'center/top', c2: 'right/top' },
  { id: 1, label: 'middle', c0: 'left/middle', c1: 'center/middle', c2: 'right/middle' },
  { id: 2, label: 'bottom', c0: 'left/bottom', c1: 'center/bottom', c2: 'right/bottom' },
];

const options2 = {
  list: list2,
  itemKey: 'id',
  estimatedSize: 80,
  buffer: 4,
  border: true,
  cellStyle: (col: any, row: any) => {
    if (col.key === 'label') return '';
    const rowIdx = row.id as number;
    const colIdx = parseInt(col.key.replace('c', ''));
    const a = alignMap[`${rowIdx},${colIdx}`];
    if (!a) return '';
    return `text-align:${a.align};vertical-align:${a.vAlign};height:80px`;
  },
};
</script>