Appearance
Table Component Demos
Basic Table
Simple table with sorting capabilities and hover effects.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
@cellClicked="handleCellClick"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email", sortable: true },
{ text: "Age", key: "age", classes: "center-align", sortable: true },
{ text: "Department", key: "department" }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
{ name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
{ name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);
const handleCellClick = (rowData, cell) => {
console.log('Cell clicked:', rowData, cell);
};
</script>Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Table with Pagination
Table with built-in pagination controls.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:enablePagination="true"
:itemsPerPage="3"
:currentPage="currentPage"
:totalItems="totalItems"
@onPageChange="handlePageChange"
/>
</template>
<script setup>
import { ref, computed } from 'vue';
const headers = [
{ text: "ID", key: "id", sortable: true },
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email" },
{ text: "Status", key: "status", classes: "center-align" }
];
const tableData = ref([
{ id: 1, name: "John Doe", email: "john@example.com", status: "Active" },
{ id: 2, name: "Jane Smith", email: "jane@example.com", status: "Active" },
{ id: 3, name: "Bob Johnson", email: "bob@example.com", status: "Inactive" },
{ id: 4, name: "Alice Brown", email: "alice@example.com", status: "Active" },
{ id: 5, name: "Charlie Wilson", email: "charlie@example.com", status: "Active" }
]);
const currentPage = ref(1);
const totalItems = computed(() => tableData.value.length);
const handlePageChange = (page) => {
currentPage.value = page;
};
</script>ID
Name
Email
Status
1
John Doe
john@example.com
Active
2
Jane Smith
jane@example.com
Active
3
Bob Johnson
bob@example.com
Inactive
Page 1 of 3
Table with Custom Cell Content
Table with custom cell rendering using slots.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
@cellClicked="handleCellClick"
>
<template #cell-status="{ rowData }">
<span :class="['status-badge', rowData.status.toLowerCase()]">
{{ rowData.status }}
</span>
</template>
<template #cell-actions="{ rowData }">
<button @click="editUser(rowData)" class="edit-btn">Edit</button>
<button @click="deleteUser(rowData)" class="delete-btn">Delete</button>
</template>
</OTable>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email" },
{ text: "Status", key: "status" },
{ text: "Actions", key: "actions", classes: "center-align" }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", status: "Active" },
{ name: "Jane Smith", email: "jane@example.com", status: "Inactive" },
{ name: "Bob Johnson", email: "bob@example.com", status: "Active" }
]);
const editUser = (user) => {
console.log('Edit user:', user);
};
const deleteUser = (user) => {
console.log('Delete user:', user);
};
</script>Name
Email
Status
Actions
John Doe
john@example.com
Active
Jane Smith
jane@example.com
Inactive
Bob Johnson
bob@example.com
Active
Table with Alternate Row Colors
Table with alternating row background colors for better readability.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:isAlternateRowColored="true"
@cellClicked="handleCellClick"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email", sortable: true },
{ text: "Age", key: "age", classes: "center-align", sortable: true },
{ text: "Department", key: "department" }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
{ name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
{ name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);
</script>Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Table with Alternate Column Colors
Table with alternating column background colors.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:isAlternateColumnColored="true"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name" },
{ text: "Email", key: "email" },
{ text: "Role", key: "role" },
{ text: "Status", key: "status" }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", role: "Developer", status: "Active" },
{ name: "Jane Smith", email: "jane@example.com", role: "Designer", status: "Active" },
{ name: "Bob Johnson", email: "bob@example.com", role: "Manager", status: "Away" }
]);
</script>Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Table with Both Row and Column Colors
Table with both alternating row and column colors.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:isAlternateRowColored="true"
:isAlternateColumnColored="true"
/>
</template>Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Table with Infinite Scroll
Table with infinite scroll functionality for loading more data.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:enableInfiniteScroll="true"
@scrolledToEndInTable="loadMoreData"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email", sortable: true },
{ text: "Age", key: "age", classes: "center-align", sortable: true },
{ text: "Department", key: "department" }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", age: 30, department: "Engineering" },
{ name: "Jane Smith", email: "jane@example.com", age: 25, department: "Marketing" },
{ name: "Bob Johnson", email: "bob@example.com", age: 35, department: "Sales" }
]);
const loadMoreData = () => {
console.log('Loading more data...');
// In a real application, you would fetch more data from an API
// and append it to tableData
};
</script>Name
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Table with Data Transformation
Table using domFunc to transform cell data before display.
vue
<template>
<OTable
:headers="headers"
:tableData="data"
/>
</template>
<script setup>
import { ref } from 'vue';
const formatDate = (dateString) => {
if (!dateString) return '-';
const date = new Date(dateString);
return date.toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric'
});
};
const formatCurrency = (value) => {
if (!value && value !== 0) return '-';
return `$${parseFloat(value).toFixed(2)}`;
};
const headers = [
{ text: "Name", key: "name" },
{ text: "Joined Date", key: "joinedDate", domFunc: formatDate },
{ text: "Salary", key: "salary", domFunc: formatCurrency, classes: "right-align" }
];
const data = ref([
{ name: "John Doe", joinedDate: "2022-01-15", salary: 75000 },
{ name: "Jane Smith", joinedDate: "2021-06-22", salary: 82000 },
{ name: "Bob Johnson", joinedDate: "2023-03-10", salary: 65000 },
{ name: "Alice Brown", joinedDate: "2022-11-05", salary: 78000 }
]);
</script>Name
Joined Date
Salary
John Doe
Jan 15, 2022
$75000.00
Jane Smith
Jun 22, 2021
$82000.00
Bob Johnson
Mar 10, 2023
$65000.00
Alice Brown
Nov 5, 2022
$78000.00
Table with Copy Functionality
Table with copy to clipboard functionality for specific columns.
vue
<template>
<OTable
:headers="headers"
:tableData="data"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", enableCopy: true, headerClasses: "right-align" },
{ text: "Email", key: "email", enableCopy: true },
{ text: "ID", key: "id", enableCopy: true, classes: "center-align" }
];
const data = ref([
{ name: "John Doe", email: "john@example.com", id: "EMP001" },
{ name: "Jane Smith", email: "jane@example.com", id: "EMP002" },
{ name: "Bob Johnson", email: "bob@example.com", id: "EMP003" }
]);
</script>Name
Email
ID
John Doe
john@example.com
EMP001
Jane Smith
jane@example.com
EMP002
Bob Johnson
bob@example.com
EMP003
Table with Custom Column Widths
Table with custom column widths.
vue
<template>
<OTable
:headers="headers"
:tableData="data"
:defaultCellWidth="'1fr'"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", width: "200px" },
{ text: "Email", key: "email", width: "250px" },
{ text: "Role", key: "role", width: "150px" },
{ text: "Status", key: "status" }
];
const data = ref([
{ name: "John Doe", email: "john@example.com", role: "Developer", status: "Active" },
{ name: "Jane Smith", email: "jane@example.com", role: "Designer", status: "Active" },
{ name: "Bob Johnson", email: "bob@example.com", role: "Manager", status: "Away" }
]);
</script>Name
Email
Role
Status
John Doe
john@example.com
Developer
Active
Jane Smith
jane@example.com
Designer
Active
Bob Johnson
bob@example.com
Manager
Away
Table with Custom Headers
Table with custom header content using header slots.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
@cellClicked="handleCellClick"
>
<template #header-name="{ cell }">
<div class="custom-header">
<span>{{ cell.text }}</span>
<span class="required">*</span>
</div>
</template>
<template #header-email="{ cell }">
<div class="custom-header">
<span>{{ cell.text }}</span>
<span class="info-icon">ℹ️</span>
</div>
</template>
</OTable>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email", sortable: true },
{ text: "Age", key: "age", classes: "center-align", sortable: true }
];
const tableData = ref([
{ name: "John Doe", email: "john@example.com", age: 30 },
{ name: "Jane Smith", email: "jane@example.com", age: 25 },
{ name: "Bob Johnson", email: "bob@example.com", age: 35 }
]);
</script>Name*
Email
Age
Department
John Doe
john@example.com
30
Engineering
Jane Smith
jane@example.com
25
Marketing
Bob Johnson
bob@example.com
35
Sales
Alice Brown
alice@example.com
28
HR
Charlie Wilson
charlie@example.com
32
Engineering
Async Table with Server-side Sorting
Table configured for server-side data handling with async mode.
vue
<template>
<OTable
:headers="headers"
:tableData="tableData"
:async="true"
:enablePagination="true"
:currentPage="currentPage"
:totalItems="totalItems"
@onSort="handleSort"
@onPageChange="handlePageChange"
/>
</template>
<script setup>
import { ref } from 'vue';
const headers = [
{ text: "Name", key: "name", sortable: true },
{ text: "Email", key: "email", sortable: true },
{ text: "Created", key: "createdAt", sortable: true }
];
const tableData = ref([]);
const currentPage = ref(1);
const totalItems = ref(0);
const handleSort = ({ key, direction }) => {
console.log('Sort:', key, direction);
// Handle sorting on the server
};
const handlePageChange = (page) => {
currentPage.value = page;
// Handle page change on the server
};
</script>ID
Name
Email
Status
1
John Doe
john@example.com
Active
2
Jane Smith
jane@example.com
Active
3
Bob Johnson
bob@example.com
Inactive
4
Alice Brown
alice@example.com
Active
5
Charlie Wilson
charlie@example.com
Active
6
Diana Prince
diana@example.com
Inactive
7
Edward Norton
edward@example.com
Active
8
Fiona Gallagher
fiona@example.com
Active
Page 1 of 1