Giao diện
CTable — trạng thái bảng
Đang tải, có dữ liệu, rỗng, lỗi — bốn trạng thái mà mọi bảng đều gặp. Bỏ sót một trạng thái là cách nhanh nhất để người dùng nhìn thấy màn hình trắng không giải thích.
Đang tải
vue
<CTable :loading="loading" />loading từ useTable đã bật/tắt đúng lúc. Trong khi tải, bảng phủ lớp mờ và icon "Tải lại" trên toolbar tự xoay — không cần thêm chỉ báo nào khác.
Nhận cả dạng object của antd khi cần tuỳ biến:
vue
<CTable :loading="{ spinning: loading, tip: 'Đang tải đơn hàng…' }" />Lần tải đầu tiên nên để bảng rỗng kèm loading thay vì hiện dữ liệu cũ của màn hình trước.
Rỗng
Mặc định bảng hiện phần rỗng của antd ("Không có dữ liệu"). Nói rõ hơn bằng slot #emptyText:
vue
<template #emptyText>
<CEmpty description="Không có đơn hàng nào khớp điều kiện lọc.">
<CButton variant="outline" @click="clearFilters">Xoá bộ lọc</CButton>
</CEmpty>
</template>Phân biệt hai tình huống — chúng cần hai lời mời khác nhau:
| Tình huống | Câu chữ | Hành động |
|---|---|---|
| Chưa có bản ghi nào | "Chưa có đơn hàng nào." | Tạo mới |
| Bộ lọc không ra kết quả | "Không có đơn hàng nào khớp điều kiện lọc." | Xoá bộ lọc |
Xem thêm CEmpty.
Lỗi
CTable không có trạng thái lỗi riêng: khi fetcher hỏng, useTable giữ lỗi ở error và bảng chỉ đơn giản không có dữ liệu. Trang tự quyết định hiển thị:
vue
<CEmpty v-if="error" :description="error.message" bordered>
<CButton variant="primary" @click="reload">Thử lại</CButton>
</CEmpty>
<CTable v-else :data-source="dataSource" :loading="loading" />Lỗi của lần tải đầu tiên cần xử lý tường minh — xem Trang danh sách.
Dòng xen kẽ và lớp dòng
vue
<CTable striped />striped thêm nền cho dòng chẵn, dễ đọc với bảng nhiều cột. Vẫn dùng được row-class-name của riêng trang — CTable gộp hai lớp lại:
vue
<CTable
striped
:row-class-name="(record) => (record as Order).status === 'cancelled' ? 'row--cancelled' : ''"
/>Chọn dòng và hành động hàng loạt
row-selection là tính năng gốc của a-table, được chuyển tiếp nguyên vẹn:
vue
<script setup lang="ts">
const selectedKeys = ref<number[]>([])
const rowSelection = computed(() => ({
selectedRowKeys: selectedKeys.value,
onChange: (keys: (string | number)[]) => {
selectedKeys.value = keys.map(Number)
},
}))
</script>
<template>
<CTable :row-selection="rowSelection" row-key="id" />
<template #toolbar>
<CButton
v-if="selectedKeys.length"
variant="danger"
size="sm"
@click="removeSelected"
>
Xoá {{ selectedKeys.length }} đơn
</CButton>
</template>
</template>row-keyphải đúng, nếu không lựa chọn sẽ nhảy lung tung khi đổi trang.- Lựa chọn không tự giữ qua các trang: muốn giữ thì tự gom
selectedKeysnhư trên. - Hành động hàng loạt có tính phá huỷ thì hỏi lại và nêu rõ số bản ghi bị ảnh hưởng.