Время чтения: 3 мин.
В Vue.js использование слотов (slots) позволяет создавать гибкие и переиспользуемые компоненты, включая таблицы. Слоты позволяют вставлять произвольное содержимое в определённые места компонента. В случае с таблицей, вы можете использовать слоты для кастомизации отображения строк, ячеек, заголовков и других элементов.
Реализация компонента таблицы
Компонент MyTable.vue
<template>
<table>
<!-- Шапка таблицы -->
<thead>
<tr>
<!-- Проходим по колонкам и создаем заголовки -->
<th v-for="column in columns" :key="column.key">
{{ column.label }}
</th>
</tr>
</thead>
<!-- Тело таблицы -->
<tbody>
<!-- Проходим по данным и создаем строки -->
<tr v-for="(row, rowIndex) in data" :key="rowIndex">
<!-- Проходим по колонкам и создаем ячейки -->
<td v-for="column in columns" :key="column.key">
<!-- Слот для переопределения отображения ячейки -->
<slot :name="`cell-${column.key}`" :row="row" :value="row[column.key]">
<!-- По умолчанию отображаем значение row[column.key] -->
{{ row[column.key] }}
</slot>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
props: {
columns: {
type: Array,
required: true,
validator: (value) => {
// Проверяем, что каждая колонка имеет key и label
return value.every((column) => column.key && column.label);
},
},
data: {
type: Array,
required: true,
},
},
};
</script>
<style scoped>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f4f4f4;
}
</style>
Использование компонента с переопределением ячеек
Теперь вы можете использовать компонент MyTable
и переопределять отображение ячеек через именованные слоты.
Пример использования
<template>
<div>
<MyTable :columns="columns" :data="data">
<!-- Переопределяем отображение ячейки для колонки "age" -->
<template #cell-age="{ value }">
<span style="color: red;">{{ value }} лет</span>
</template>
<!-- Переопределяем отображение ячейки для колонки "actions" -->
<template #cell-actions="{ row }">
<button @click="editRow(row)">Редактировать</button>
<button @click="deleteRow(row)">Удалить</button>
</template>
</MyTable>
</div>
</template>
<script>
import MyTable from './MyTable.vue';
export default {
components: {
MyTable,
},
data() {
return {
// Колонки таблицы
columns: [
{ key: 'name', label: 'Имя' },
{ key: 'age', label: 'Возраст' },
{ key: 'actions', label: 'Действия' }, // Добавляем колонку для действий
],
// Данные таблицы
data: [
{ name: 'Иван', age: 25 },
{ name: 'Мария', age: 30 },
{ name: 'Петр', age: 28 },
],
};
},
methods: {
editRow(row) {
alert(`Редактировать: ${row.name}`);
},
deleteRow(row) {
alert(`Удалить: ${row.name}`);
},
},
};
</script>
Объяснение
- Компонент
MyTable
:- Принимает два пропса:
columns
: массив объектов, где каждый объект описывает колонку (обязательные поля:key
иlabel
).data
: массив объектов, где каждый объект представляет строку данных.
- Шапка таблицы (
<thead>
) строится автоматически на основеcolumns
. - Тело таблицы (
<tbody>
) отображает данные по умолчанию, используяcolumn.key
для доступа к значениям. - Для каждой ячейки предоставляется слот с именем
cell-${column.key}
, который позволяет переопределить отображение.
- Принимает два пропса:
- Использование слотов:
- В родительском компоненте можно переопределить отображение ячеек, используя именованные слоты, например,
#cell-age
или#cell-actions
. - В слот передаются параметры:
row
: текущая строка данных.value
: значение ячейки (row[column.key]
).
- В родительском компоненте можно переопределить отображение ячеек, используя именованные слоты, например,
- Гибкость:
- Если слот для конкретной ячейки не переопределён, используется значение по умолчанию (
row[column.key]
). - Вы можете добавлять кастомные элементы, такие как кнопки, иконки или стилизованные тексты.
- Если слот для конкретной ячейки не переопределён, используется значение по умолчанию (
Результат
- Шапка таблицы будет отображать заголовки, переданные в
columns
. - Строки таблицы будут отображать данные по умолчанию, но вы можете переопределить отображение для любой колонки через слоты.
- Например, для колонки
age
текст будет красным, а для колонкиactions
будут отображаться кнопки.
Этот подход обеспечивает максимальную гибкость и переиспользуемость компонента таблицы.
Добавить комментарий