I am currently working with a relatively large Vue (Vue 2) project that uses a lot of tables, and I want to create a reusable table component where each column is a child component / slot. Something like this:
<Table :data="data">
<TableColumn field="id" label="ID" />
<TableColumn field="name" label="Name" />
<TableColumn field="date_created" label="Created" />
</Table>
const data = [
{ id: 1, name: 'Foo', date_created: '01.01.2021' },
{ id: 2, name: 'Bar', date_created: '01.01.2021' }
];
Which in turn should output this:
<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Created</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Foo</td>
<td>01.01.2021</td>
</tr>
<tr>
<td>2</td>
<td>Bar</td>
<td>01.01.2021</td>
</tr>
</tbody>
</table>
We've previously used Buefy, but the vendor size becomes unnecessarily large, as we only use a fraction of the components' functionality - so I want to create a lightweight alternative.
CodePudding user response:
With this data you only need 2 Props, labels and data.
<!-- Component -->
<table>
<thead>
<tr>
<td v-for="(label, labelIndex) in labels" :key="labelIndex">
{{ label.text }}
</td>
</tr>
</thead>
<tbody>
<tr v-for="(item, itemIndex) in data" :key="itemIndex">
<td v-for="(label, labelIndex) in labels" :key="labelIndex">
{{ item[label.field] }}
</td>
</tr>
</tbody>
</table>
// Data and labels
const labels = [
{ text: ID, field: id },
{ text: Name, field: name },
{ text: Created, field: date_created },
]
const data = [
{ id: 1, name: 'Foo', date_created: '01.01.2021' },
{ id: 2, name: 'Bar', date_created: '01.01.2021' }
];
<table-component
:labels="labels"
:data="data"
>
</table-component>
If you need something more complex you can use nested components combined with a named slots for the header or footer of the table (or other options like search).