Table
Display multiple data with similar format.
Basic
Name | Age | Address |
---|---|---|
Mike | 32 | 10 Downing Street |
John | 42 | 10 Downing Street |
Basic Usage
Basic table is just for data display.
<template>
<v-table :dataSource="dataSource" :columns="columns"> </v-table>
</template>
<script setup lang="ts">
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
</script>
Border
Name | Age | Address |
---|---|---|
Mike | 32 | 10 Downing Street |
John | 42 | 10 Downing Street |
Border
Use the bordered attribute to set the table display border.
<template>
<v-table bordered :dataSource="dataSource" :columns="columns"> </v-table>
</template>
<script setup lang="ts">
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
</script>
Header And Footer
ET
HeaderName | Age | Address |
---|---|---|
Mike | 32 | 10 Downing Street |
John | 42 | 10 Downing Street |
Customizing the header and footer
Customizing the header and footer of table by setting header and footer property.
<template>
<v-table bordered :dataSource="dataSource" :columns="columns">
<template #header>
<div :style="{ display: 'flex', alignItems: 'center' }">
<v-avatar name="Eobard Thawne" size="32px" />
<span :style="{ marginLeft: '15px' }"> Header</span>
</div>
</template>
<template #footer>
<div :style="{ display: 'flex', alignItems: 'center' }">
<v-avatar name="Eobard Thawne" size="32px" />
<span :style="{ marginLeft: '15px' }"> Footer</span>
</div>
</template>
</v-table>
</template>
<script setup lang="ts">
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
{
key: '2',
name: 'John',
age: 42,
address: '10 Downing Street',
},
];
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
</script>
Custom Cells
Custom Cell Presentation
Name | Age | Address | Operation |
---|---|---|---|
Edward King 0 | 32 | London, Park Lane no. 0 | |
Edward King 1 | 32 | London, Park Lane no. 1 |
Custom Cells
Customize cells through slots.
<template>
<v-button size="mini" type="primary" style="margin-bottom: 8px" @click="handleAdd">Add</v-button>
<v-table bordered :dataSource="dataSource" :columns="columns">
<template #header> Custom Cell Presentation </template>
<template #headerCell="{ column }">
<template v-if="column.key === 'name'">
<span style="display: flex; align-items: center">
<v-avatar src="https://avatars.dicebear.com/api/human/yard.svg?width=285&mood=happy" size="16px" />
Name
</span>
</template>
</template>
<template #bodyCell="{ column, text, record }">
<template v-if="column.dataIndex === 'name'">
<div v-if="editableData[record.key]" class="editable-cell-wrapper">
<v-input size="mini" v-model="editableData[record.key].name" />
<v-button size="mini" class="editable-btn" @click="save(record.key)">save</v-button>
</div>
<div v-else class="editable-cell-wrapper">
{{ text || ' ' }}
<v-button size="mini" class="editable-btn" @click="edit(record.key)">edit</v-button>
</div>
</template>
<template v-if="column.dataIndex === 'address'">
<v-link style="color: red">{{ text }}</v-link>
</template>
<template v-if="column.dataIndex === 'operation'">
<v-button size="mini" type="primary" @click="onDelete(record.key)">delete</v-button>
</template>
</template>
<template #footer>
<div :style="{ display: 'flex', alignItems: 'center' }">
<v-avatar name="Eobard Thawne" size="32px" />
<span :style="{ marginLeft: '15px' }"> Footer</span>
</div>
</template>
</v-table>
</template>
<script setup lang="ts">
import { ref, computed, reactive } from 'vue';
import type { Ref, UnwrapRef } from 'vue';
interface DataItem {
key: string;
name: string;
age: number;
address: string;
}
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
{
title: 'Operation',
dataIndex: 'operation',
key: 'operation',
},
];
let dataSource: Ref<DataItem[]> = ref([
{
key: '0',
name: 'Edward King 0',
age: 32,
address: 'London, Park Lane no. 0',
},
{
key: '1',
name: 'Edward King 1',
age: 32,
address: 'London, Park Lane no. 1',
},
]);
const count = computed(() => dataSource.value.length + 1);
const editableData: UnwrapRef<Record<string, DataItem>> = reactive({});
const edit = (key: string) => {
editableData[key] = JSON.parse(JSON.stringify(dataSource.value.find(item => key === item.key)));
};
const save = (key: string) => {
Object.assign(dataSource.value.find(item => key === item.key) as DataItem, editableData[key]);
delete editableData[key];
};
const handleAdd = () => {
const newData = {
key: `${count.value}`,
name: `Edward King ${count.value}`,
age: 32,
address: `London, Park Lane no. ${count.value}`,
};
dataSource.value.push(newData);
};
const onDelete = (key: string) => {
dataSource.value = dataSource.value.filter(item => item.key !== key);
};
</script>
<style scoped>
.editable-cell-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
}
.editable-btn {
margin-left: 5px;
}
</style>
Fixed Header
Name | Age | Address |
---|
Edward King 0 | 32 | London, Park Lane no. 0 |
Edward King 1 | 32 | London, Park Lane no. 1 |
Edward King 2 | 32 | London, Park Lane no. 2 |
Edward King 3 | 32 | London, Park Lane no. 3 |
Edward King 4 | 32 | London, Park Lane no. 4 |
Edward King 5 | 32 | London, Park Lane no. 5 |
Edward King 6 | 32 | London, Park Lane no. 6 |
Edward King 7 | 32 | London, Park Lane no. 7 |
Edward King 8 | 32 | London, Park Lane no. 8 |
Edward King 9 | 32 | London, Park Lane no. 9 |
Fixed Header
Display large amounts of data in scrollable view. Specify width of columns if header and cell do not align properly. If specified width is not working or have gutter between columns, please try to leave one column at least without width to fit fluid layout, or make sure no long word to break table layout.
<template>
<v-table height="240px" bordered :dataSource="dataSource" :columns="columns"> </v-table>
</template>
<script setup lang="ts">
const dataSource = [...Array(10)].map((_, i) => ({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
}));
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
width: 150, // 🚨 Specify width of columns
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
width: 150, // 🚨 Specify width of columns
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
</script>
Fixed Columns
Full Name | Age | Column 1 | Column 2 | Column 3 | Column 4 | Column 5 | Column 6 | Column 7 | Column 8 |
---|---|---|---|---|---|---|---|---|---|
Edward King 0 | 32 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 |
Edward King 1 | 32 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 |
Edward King 2 | 32 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 |
Edward King 3 | 32 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 |
Fixed Columns
To fix some columns and scroll inside other columns,The actual content width can be set through scrollWidth.
<template>
<v-table :scrollWidth="2000" bordered :dataSource="dataSource" :columns="columnsFixed"> </v-table>
</template>
<script setup lang="ts">
interface ColumnProps {
dataIndex?: string;
title: string;
key: string;
width?: number | string;
fixed?: boolean | string;
}
const dataSource = [...Array(4)].map((_, i) => ({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
}));
const columnsFixed: Array<ColumnProps> = [
{ title: 'Full Name', width: 200, dataIndex: 'name', key: 'name', fixed: 'left' },
{ title: 'Age', width: 50, dataIndex: 'age', key: 'age' },
{ title: 'Column 1', dataIndex: 'address', key: '1' },
{ title: 'Column 2', dataIndex: 'address', key: '2' },
{ title: 'Column 3', dataIndex: 'address', key: '3' },
{ title: 'Column 4', dataIndex: 'address', key: '4' },
{ title: 'Column 5', dataIndex: 'address', key: '5' },
{ title: 'Column 6', dataIndex: 'address', key: '6' },
{ title: 'Column 7', dataIndex: 'address', key: '7' },
{ title: 'Column 8', dataIndex: 'address', key: '8', fixed: 'right' },
];
</script>
Fixed Header And Columns
Full Name | Age | Column 1 | Column 2 | Column 3 | Column 4 | Column 5 | Column 6 | Column 7 | Column 8 |
---|
Edward King 0 | 32 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 | London, Park Lane no. 0 |
Edward King 1 | 32 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 | London, Park Lane no. 1 |
Edward King 2 | 32 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 | London, Park Lane no. 2 |
Edward King 3 | 32 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 | London, Park Lane no. 3 |
Edward King 4 | 32 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 | London, Park Lane no. 4 |
Edward King 5 | 32 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 | London, Park Lane no. 5 |
Edward King 6 | 32 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 | London, Park Lane no. 6 |
Edward King 7 | 32 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 | London, Park Lane no. 7 |
Edward King 8 | 32 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 | London, Park Lane no. 8 |
Edward King 9 | 32 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 | London, Park Lane no. 9 |
Fixed Head And Column
A Solution for displaying large amounts of data with long columns.
<template>
<v-table height="240px" :scrollWidth="2000" bordered :dataSource="dataSource" :columns="columnsFixed" />
</template>
<script setup lang="ts">
interface ColumnProps {
dataIndex?: string;
title: string;
key: string;
width?: number | string;
fixed?: boolean | string;
}
const dataSource = [...Array(10)].map((_, i) => ({
key: i,
name: `Edward King ${i}`,
age: 32,
address: `London, Park Lane no. ${i}`,
}));
const columnsFixed: Array<ColumnProps> = [
{ title: 'Full Name', width: 200, dataIndex: 'name', key: 'name', fixed: 'left' },
{ title: 'Age', width: 60, dataIndex: 'age', key: 'age' },
{ title: 'Column 1', dataIndex: 'address', key: '1' },
{ title: 'Column 2', dataIndex: 'address', key: '2' },
{ title: 'Column 3', dataIndex: 'address', key: '3' },
{ title: 'Column 4', dataIndex: 'address', key: '4' },
{ title: 'Column 5', dataIndex: 'address', key: '5' },
{ title: 'Column 6', dataIndex: 'address', key: '6' },
{ title: 'Column 7', dataIndex: 'address', key: '7' },
{ title: 'Column 8', dataIndex: 'address', key: '8', fixed: 'right' },
];
</script>