Files
edgeKey/components/DataTable.vue
2026-04-24 15:35:40 +08:00

66 lines
2.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="space-y-3">
<div class="overflow-x-auto overflow-y-auto max-h-150">
<table class="table table-zebra w-full">
<thead class="sticky top-0 z-10 bg-base-200">
<tr>
<th v-for="col in columns" :key="col.key">{{ col.label }}</th>
</tr>
</thead>
<tbody>
<tr v-if="!rows.length">
<td :colspan="columns.length" class="text-center text-base-content/60">{{ emptyText }}</td>
</tr>
<tr v-for="(row, i) in rows" :key="i">
<td v-for="col in columns" :key="col.key">
<slot :name="col.key" :row="row" :value="row[col.key]">{{ row[col.key] ?? '-' }}</slot>
</td>
</tr>
</tbody>
</table>
</div>
<div v-if="total > pageSize" class="flex items-center justify-between">
<span class="text-sm text-base-content/60"> {{ total }} {{ page }}/{{ totalPages }} </span>
<div class="join">
<button class="join-item btn btn-sm" :disabled="page <= 1" @click="$emit('update:page', page - 1)">«</button>
<button
v-for="p in pageNumbers"
:key="p"
class="join-item btn btn-sm"
:class="{ 'btn-active': p === page }"
@click="$emit('update:page', p)"
>{{ p }}</button>
<button class="join-item btn btn-sm" :disabled="page >= totalPages" @click="$emit('update:page', page + 1)">»</button>
</div>
</div>
</div>
</template>
<script setup lang="ts" generic="T extends Record<string, any>">
import { computed } from "vue";
const props = withDefaults(defineProps<{
columns: { key: string; label: string }[];
rows: T[];
total: number;
page: number;
pageSize?: number;
emptyText?: string;
}>(), {
pageSize: 20,
emptyText: "暂无数据",
});
defineEmits<{ "update:page": [page: number] }>();
const totalPages = computed(() => Math.max(1, Math.ceil(props.total / props.pageSize)));
const pageNumbers = computed(() => {
const pages: number[] = [];
const start = Math.max(1, props.page - 2);
const end = Math.min(totalPages.value, start + 4);
for (let i = start; i <= end; i++) pages.push(i);
return pages;
});
</script>