@tigerbui/i-table-vuetifyjs
v1.1.7
Published
Cập nhật thêm UI/UX table dựa trên framework vuetifyjs
Downloads
67
Readme
Table of Contents
| Content | | ------------------------------------------------------------------------------------------------------------ | | Quick start - NPM - Usage | | Interface custom | | Api - Search | | Event custom | | Slots - Attrs - Check box selected - Vuetifyjs |
Quick start
NPM
npm i @tigerbui/i-table-vuetifyjs@latest
Usage
<script setup lang="ts">
import ITableVuetify from "@tigerbui/i-table-vuetifyjs";
import { ref } from "vue";
const desserts = ref<any[]>([]);
Array.from({ length: 200 }, (_, _id: number) => {
const floor: string = Math.floor(Math.random() * _id).toFixed(2);
const Int: number = Math.ceil(Math.random() * _id);
desserts.value.push({
name: `Name ${_id}`,
calories: Int,
fat: floor,
carbs: Int,
protein: floor,
iron: floor,
});
});
const headers = ref<any[]>([
{
title: "Dessert (100g serving)",
align: "start",
sortable: false,
key: "name",
},
{ title: "Calories", key: "calories", align: "end" },
{ title: "Fat (g)", key: "fat", align: "end" },
{ title: "Carbs (g)", key: "carbs", align: "end" },
{ title: "Protein (g)", key: "protein", align: "end" },
{ title: "Iron (%)", key: "iron", align: "end" },
]);
</script>
<template>
<h1>Demo Vu3</h1>
<ITableVuetify
:headers="headers"
:items="desserts"
show-select
></ITableVuetify>
</template>
Interface custom
interface ITableType {
api?: string | boolean
headers: HeadersType[]
itemsLength?: number
items?: any[]
loading?: boolean
pages?: number
apiCustom?: ApiCustomType
}
| Tên prop | Type | Ghi chú |
| :--- | --- | --- |
| api | boolean - string
| Khi cần ghép API từ bên ngoài cần enable api: true
|
| pages | number
| Ex: /api/character?page=${page}
|
| apiCustom | ApiCustomType | Tuỳ chọn khi kết nối API |
Events custom
- Các event khác vẫn giữ nguyên của Vuetifyjs
| Name | Type |
| :----------------------------------------------------------------------------------- | --------- |
| deleteAllCallback | [any]
|
| Emits này chỉ hoạt động khi prop: api='true'. Sau đó checkbox row và bấm nút Xoá |
Slots
- None: không có dữ liệu từ props table trả về
| Tên | Ghi chú | | :--- | --- | | table.header.title | { items: any[] } | | Định nghĩa phần tiêu đề của table, phần này phụ thuộc vào $attrs card-title, nếu card-title="false" phần header table sẽ không hiển thị | | table.extend.left | None | | Định nghĩa nội dung nằm bên trái của Ô tìm kiếm | | table.extend.right | None | | Định nghĩa nội dung nằm bên phải của Ô tìm kiếm |
Attrs
| Tên attrs | Ghi chú |
| :--- | --- |
| table.header.title | Mặc định sử dụng <ITableVuetify header-title='Title'/>
|
| Muốn tuỳ chọn thì sử dụng slot table.header.title |
Check box selected
- Khi checkbox được kích hoạt
| Tên slot | |
| :------------------------------------------------ | ------------------------------------------ |
| table.selected.left | None - Default: Đã chọn { items.lenght }
|
| Định nghĩa nội dung nằm bên trái |
| table.selected.center | None |
| Định nghĩa nội dung nằm giữa |
| table.selected.actions | None - Mặc định là nút Xoá tất cả |
| Định nghĩa actions cũng như nội dung nằm bên phải |
Vuetifyjs data table
Các nội dung về event, props,.. vẫn giữ nguyên của Vuetifyjs docs
- Ở ITableVuetifyjs thì slots v-data-table chỉ có
| Tên slot | |
| :--- | --- |
| [`item.${string}`] | { index: number, item: any}
|
| Slot tuỳ chọn cho 1 cột trong hàng | |
| table.tfoot | { items: any[], columns: InternalDataTableHeader[] }
|
| Slot to replace the default table | |
| bottom | { page: number }
|
| Slot tuỳ chọn cho data table footer | |
Api data table server
- Tuỳ chọn khi props
:api='true'
Slot
| Name | Type |
| :--- | --- |
| search | (item: any, query: string) => boolean
|
| Custom search từ props :api-custom={search: (item: any, query: string) => searchCustom(item, query)}
|
Api event
| Tên | Type |
| :--- | --- |
| api-page | [number]
|
| ex: @api-page="(page: number) => DemoTable.isApi(page)"
|
Demo Api
<script setup lang="ts">
import { onMounted, ref } from "vue";
import ITableVuetify from "@tigerbui/i-table-vuetifyjs"
const desserts = ref<any[]>([]);
const headers = ref<any[]>([]);
const closeModal = ref<boolean>(false)
type DataInfo = {
count: number
next: string | null
pages: number
prev: string | null
}
const DemoTable = ref<any>({
api: true,
apiInfor: {
count: 0,
next: '',
pages: 0,
prev: ''
} as DataInfo,
itemsPerpage: 5,
notApi: () => {
headers.value = [
{
title: "Dessert (100g serving)",
align: "start",
sortable: false,
key: "name",
},
{ title: "Calories", key: "calories", align: "end" },
{ title: "Fat (g)", key: "fat", align: "end" },
{ title: "Carbs (g)", key: "carbs", align: "end" },
{ title: "Protein (g)", key: "protein", align: "end" },
{ title: "Iron (%)", key: "iron", align: "end" },
]
Array.from({ length: 200 }, (_, _id: number) => {
const floor: string = Math.floor(Math.random() * _id).toFixed(2);
const Int: number = Math.ceil(Math.random() * _id);
desserts.value.push({
name: `Name ${_id}`,
calories: Int,
fat: floor,
carbs: Int,
protein: floor,
iron: floor,
});
});
},
isApi: async (page: number) => {
headers.value = [
{
title: "Tên",
key: "name"
},
{
title: "Giới tính",
key: "gender"
},
{
title: "Trạng thái",
key: "status"
},
{
title: "Ảnh",
key: "image"
}
]
const response = await fetch(`https://rickandmortyapi.com/api/character?page=${page}`);
const data = await response.json();
DemoTable.value.apiInfor = data.info;
data.results.forEach((_it: any) => {
desserts.value.push(_it)
})
}
})
// Tìm kiếm api custom
const searchCustom = (item: any, query: string) => {
if(!query) {
item.mark = ""
return item;
}
const name: boolean = String(item.name).toLowerCase().includes(query);
if(name) {
item.mark = item.name.replace(new RegExp(query, 'ig'), `<span class='text-warning'>${query}</span>`)
}
return name
}
</script>
<template>
<v-app>
<v-container>
<h1 class="mb-5">Demo table</h1>
<ITableVuetify
:api="true"
:headers="headers"
:items="desserts"
:show-select="true"
v-model:dialog="closeModal"
:items-length="DemoTable.apiInfor.count"
:page="DemoTable.apiInfor.pages"
:api-custom={
search: (item: any, query: string) => searchCustom(item, query)
}
@api-page="(page: number) => DemoTable.isApi(page)"
>
<template #item.name="{ item }">
<span v-if="item.mark" v-html="item.mark"></span>
<template v-else>{{ item.name }}</template>
</template>
<template #item.image="{ item }">
<v-img
:aspect-ratio="1"
:src="item.image"
rounded="circle"
width="45"
cover
/>
</template>
</ITableVuetify>
</v-container>
</v-app>
</template>
<style lang="scss" scoped>
.app-page {
background-color: white;
min-height: calc(100vh - 2rem);
padding: 1rem;
.container {
width: 1000px;
margin: 0 auto;
}
.tig-table-ui {
margin-top: 3rem;
margin-bottom: 2rem;
}
}
</style>