Фиксированный заголовок
Свойство scroll.y ограничивает высоту тела таблицы — при вертикальной прокрутке шапка колонок остаётся на месте.
vue
<script setup lang="ts">
import type { NTable } from '@central-design-system/components';
import { CdsTable } from '@central-design-system/components';
type TDataType = { key: number; name: string; age: number; address: string };
const columns: NTable.NColumn.TColumns<TDataType> = [
{ title: 'Имя', dataIndex: 'name', width: 150 },
{ title: 'Возраст', dataIndex: 'age', width: 150 },
{ title: 'Адрес', dataIndex: 'address' }
];
const data: TDataType[] = [...Array(100)].map((_, i) => ({
key: i,
name: `Иван Иванов ${i}`,
age: 27,
address: `г. Москва, ул. Ленина, д. ${i}`
}));
</script>
<template>
<CdsTable :columns="columns" :data="data" :pagination="{ total: 50 }" :scroll="{ y: 245 }" />
</template>Фиксированные колонки
Свойство колонки fixed: 'left' | 'right' закрепляет её при горизонтальной прокрутке. Задайте scroll.x шире контейнера, чтобы прокрутка появилась.
vue
<script setup lang="ts">
import type { NTable } from '@central-design-system/components';
import { CdsButton, CdsTable } from '@central-design-system/components';
type TDataType = { key: string; name: string; age: number; address: string };
const columns: NTable.NColumn.TColumns<TDataType> = [
{ title: 'Имя', dataIndex: 'name', key: 'name', fixed: 'left', width: 100 },
{ title: 'Возраст', dataIndex: 'age', key: 'age', fixed: 'left', width: 100 },
{ title: 'Заголовок 1', dataIndex: 'address', key: '1' },
{ title: 'Заголовок 2', dataIndex: 'address', key: '2' },
{ title: 'Заголовок 3', dataIndex: 'address', key: '3' },
{ title: 'Заголовок 4', dataIndex: 'address', key: '4' },
{ title: 'Заголовок 5', dataIndex: 'address', key: '5' },
{ title: 'Заголовок 6', dataIndex: 'address', key: '6' },
{ title: 'Заголовок 7', dataIndex: 'address', key: '7' },
{ title: 'Заголовок 8', dataIndex: 'address', key: '8' },
{ title: 'Действия', key: 'actions', fixed: 'right', width: 100 }
];
const data: TDataType[] = [
{ key: '1', name: 'Иван', age: 32, address: 'г. Москва' },
{ key: '2', name: 'Петр', age: 40, address: 'г. Пермь' },
{ key: '3', name: 'Вадим', age: 32, address: 'г. Москва' },
{ key: '4', name: 'Евгений', age: 40, address: 'г. Балашиха' }
];
</script>
<template>
<CdsTable :columns="columns" :data="data" :scroll="{ x: 1300, y: 1000 }" :pagination="{ total: 2 }">
<template #bodyCell="{ column }">
<template v-if="column.key === 'actions'">
<CdsButton size="sm" variant="soft" color="brand">Удалить</CdsButton>
</template>
</template>
</CdsTable>
</template>Фиксированные колонки и заголовок
scroll.x и scroll.y вместе закрепляют и колонки, и шапку — центр таблицы прокручивается в обе стороны.
vue
<script setup lang="ts">
import type { NTable } from '@central-design-system/components';
import { CdsButton, CdsTable } from '@central-design-system/components';
type TDataType = { key: number; name: string; age: number; address: string };
const columns: NTable.NColumn.TColumns<TDataType> = [
{ title: 'Имя', dataIndex: 'name', key: 'name', fixed: 'left', width: 100 },
{ title: 'Возраст', dataIndex: 'age', key: 'age', fixed: 'left', width: 100 },
{ title: 'Заголовок 1', dataIndex: 'address', key: '1', width: 150 },
{ title: 'Заголовок 2', dataIndex: 'address', key: '2', width: 150 },
{ title: 'Заголовок 3', dataIndex: 'address', key: '3', width: 150 },
{ title: 'Заголовок 4', dataIndex: 'address', key: '4', width: 150 },
{ title: 'Заголовок 5', dataIndex: 'address', key: '5', width: 150 },
{ title: 'Заголовок 6', dataIndex: 'address', key: '6', width: 150 },
{ title: 'Заголовок 7', dataIndex: 'address', key: '7', width: 150 },
{ title: 'Заголовок 8', dataIndex: 'address', key: '8', width: 150 },
{ title: 'Действия', key: 'actions', fixed: 'right', width: 100 }
];
const data: TDataType[] = [...Array(10)].map((_, i) => ({
key: i,
name: `Иван ${i}`,
age: 24,
address: `ул. Главная, д. ${i}`
}));
</script>
<template>
<CdsTable :columns="columns" :data="data" :scroll="{ x: 1500, y: 300 }" :pagination="false">
<template #bodyCell="{ column }">
<template v-if="column.key === 'actions'">
<CdsButton size="sm" variant="soft" color="brand">Удалить</CdsButton>
</template>
</template>
</CdsTable>
</template>Кнопки прокрутки
Таблице с горизонтальной прокруткой можно добавить кнопки скролла: возьмите DOM-узел тела таблицы (.cds-table__body) через ref компонента и меняйте его scrollLeft по клику.
vue
<script setup lang="ts">
import type { NTable } from '@central-design-system/components';
import { CdsButton, CdsTable } from '@central-design-system/components';
import { ref, unref } from 'vue';
type TDataType = { key: string; name: string; age: number; address: string };
const columns: NTable.NColumn.TColumns<TDataType> = [
{ title: 'Имя', dataIndex: 'name', key: 'name', fixed: 'left', width: 100 },
{ title: 'Возраст', dataIndex: 'age', key: 'age', fixed: 'left', width: 100 },
{ title: 'Заголовок 1', dataIndex: 'address', key: '1' },
{ title: 'Заголовок 2', dataIndex: 'address', key: '2' },
{ title: 'Заголовок 3', dataIndex: 'address', key: '3' },
{ title: 'Заголовок 4', dataIndex: 'address', key: '4' },
{ title: 'Заголовок 5', dataIndex: 'address', key: '5' },
{ title: 'Заголовок 6', dataIndex: 'address', key: '6' },
{ title: 'Заголовок 7', dataIndex: 'address', key: '7' },
{ title: 'Заголовок 8', dataIndex: 'address', key: '8' },
{ title: 'Заголовок 9', dataIndex: 'address', key: '9' },
{ title: 'Заголовок 10', dataIndex: 'address', key: '10' },
{ title: 'Действия', key: 'actions', fixed: 'right', width: 100 }
];
const data: TDataType[] = [
{ key: '1', name: 'Иван', age: 32, address: 'г. Москва' },
{ key: '2', name: 'Петр', age: 40, address: 'г. Москва' }
];
// Функционал для реализации кнопок скролла
const scrollStep = 50;
const tableRef = ref<InstanceType<typeof CdsTable> | null>(null);
function handleClickScrollButton(_event: MouseEvent, isLeft: boolean) {
const tableBody = unref(tableRef)?.$el.querySelector('.cds-table__body');
if (tableBody) {
tableBody.scrollLeft += isLeft ? -scrollStep : scrollStep;
}
}
</script>
<template>
<CdsTable ref="tableRef" :columns="columns" :data="data" :scroll="{ x: 1300, y: 1000 }" :pagination="false">
<template #header>
<div class="flex justify-between">
<div>
<h4 class="mb-2">Заголовок таблицы</h4>
<p class="text-content-secondary">Описание таблицы в слоте заголовка таблицы</p>
</div>
<div>
<CdsButton text="Действие" />
</div>
</div>
</template>
<template #toolbar>
<div class="flex justify-end">
<div class="flex gap-2">
<CdsButton
icon="chevron-left"
variant="soft"
color="neutral"
@click="(e) => handleClickScrollButton(e, true)"
/>
<CdsButton
icon="chevron-right"
variant="soft"
color="neutral"
@click="(e) => handleClickScrollButton(e, false)"
/>
</div>
</div>
</template>
<template #bodyCell="{ column }">
<template v-if="column.key === 'actions'">
<CdsButton variant="soft" color="brand" size="sm">Удалить</CdsButton>
</template>
</template>
<template #footer>
<div class="flex justify-end gap-2">
<CdsButton
icon="chevron-left"
variant="soft"
color="neutral"
@click="(e) => handleClickScrollButton(e, true)"
/>
<CdsButton
icon="chevron-right"
variant="soft"
color="neutral"
@click="(e) => handleClickScrollButton(e, false)"
/>
</div>
</template>
</CdsTable>
</template>