Improve DataTable demo performance

This commit is contained in:
mertsincan 2023-12-31 14:08:33 +00:00
parent 69d9c0875b
commit 27db388223
48 changed files with 1560 additions and 1366 deletions

View file

@ -2,103 +2,114 @@
<DocSectionText v-bind="$attrs">
<p>DataTable with selection, pagination, filtering, sorting and templating.</p>
</DocSectionText>
<div class="card">
<DataTable v-model:filters="filters" v-model:selection="selectedCustomers" :value="customers" paginator :rows="10" dataKey="id" filterDisplay="menu" :globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']">
<template #header>
<div class="flex justify-content-between">
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
<span class="p-input-icon-left">
<i class="pi pi-search" />
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
</span>
</div>
</template>
<template #empty> No customers found. </template>
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
<Column field="name" header="Name" sortable style="min-width: 14rem">
<template #body="{ data }">
{{ data.name }}
</template>
<template #filter="{ filterModel }">
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem">
<template #body="{ data }">
<div class="flex align-items-center gap-2">
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
<span>{{ data.country.name }}</span>
<DeferredDemo @load="loadDemoData">
<div class="card">
<DataTable
v-model:filters="filters"
v-model:selection="selectedCustomers"
:value="customers"
paginator
:rows="10"
dataKey="id"
filterDisplay="menu"
:globalFilterFields="['name', 'country.name', 'representative.name', 'balance', 'status']"
>
<template #header>
<div class="flex justify-content-between">
<Button type="button" icon="pi pi-filter-slash" label="Clear" outlined @click="clearFilter()" />
<span class="p-input-icon-left">
<i class="pi pi-search" />
<InputText v-model="filters['global'].value" placeholder="Keyword Search" />
</span>
</div>
</template>
<template #filter="{ filterModel }">
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
<template #body="{ data }">
<div class="flex align-items-center gap-2">
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
<span>{{ data.representative.name }}</span>
</div>
</template>
<template #filter="{ filterModel }">
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps">
<div class="flex align-items-center gap-2">
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
<span>{{ slotProps.option.name }}</span>
</div>
</template>
</MultiSelect>
</template>
</Column>
<Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem">
<template #body="{ data }">
{{ formatDate(data.date) }}
</template>
<template #filter="{ filterModel }">
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
</template>
</Column>
<Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem">
<template #body="{ data }">
{{ formatCurrency(data.balance) }}
</template>
<template #filter="{ filterModel }">
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
</template>
</Column>
<Column header="Status" sortable field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
<template #body="{ data }">
<Tag :value="data.status" :severity="getSeverity(data.status)" />
</template>
<template #filter="{ filterModel }">
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
<template #option="slotProps">
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
</template>
</Dropdown>
</template>
</Column>
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem">
<template #body="{ data }">
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
</template>
<template #filter="{ filterModel }">
<Slider v-model="filterModel.value" range class="m-3"></Slider>
<div class="flex align-items-center justify-content-between px-2">
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
</div>
</template>
</Column>
<Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
<template #body>
<Button type="button" icon="pi pi-cog" rounded />
</template>
</Column>
</DataTable>
</div>
<template #empty> No customers found. </template>
<Column selectionMode="multiple" headerStyle="width: 3rem"></Column>
<Column field="name" header="Name" sortable style="min-width: 14rem">
<template #body="{ data }">
{{ data.name }}
</template>
<template #filter="{ filterModel }">
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by name" />
</template>
</Column>
<Column header="Country" sortable sortField="country.name" filterField="country.name" style="min-width: 14rem">
<template #body="{ data }">
<div class="flex align-items-center gap-2">
<img alt="flag" src="https://primefaces.org/cdn/primevue/images/flag/flag_placeholder.png" :class="`flag flag-${data.country.code}`" style="width: 24px" />
<span>{{ data.country.name }}</span>
</div>
</template>
<template #filter="{ filterModel }">
<InputText v-model="filterModel.value" type="text" class="p-column-filter" placeholder="Search by country" />
</template>
</Column>
<Column header="Agent" sortable sortField="representative.name" filterField="representative" :showFilterMatchModes="false" :filterMenuStyle="{ width: '14rem' }" style="min-width: 14rem">
<template #body="{ data }">
<div class="flex align-items-center gap-2">
<img :alt="data.representative.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${data.representative.image}`" style="width: 32px" />
<span>{{ data.representative.name }}</span>
</div>
</template>
<template #filter="{ filterModel }">
<MultiSelect v-model="filterModel.value" :options="representatives" optionLabel="name" placeholder="Any" class="p-column-filter">
<template #option="slotProps">
<div class="flex align-items-center gap-2">
<img :alt="slotProps.option.name" :src="`https://primefaces.org/cdn/primevue/images/avatar/${slotProps.option.image}`" style="width: 32px" />
<span>{{ slotProps.option.name }}</span>
</div>
</template>
</MultiSelect>
</template>
</Column>
<Column field="date" header="Date" sortable filterField="date" dataType="date" style="min-width: 10rem">
<template #body="{ data }">
{{ formatDate(data.date) }}
</template>
<template #filter="{ filterModel }">
<Calendar v-model="filterModel.value" dateFormat="mm/dd/yy" placeholder="mm/dd/yyyy" mask="99/99/9999" />
</template>
</Column>
<Column field="balance" header="Balance" sortable filterField="balance" dataType="numeric" style="min-width: 10rem">
<template #body="{ data }">
{{ formatCurrency(data.balance) }}
</template>
<template #filter="{ filterModel }">
<InputNumber v-model="filterModel.value" mode="currency" currency="USD" locale="en-US" />
</template>
</Column>
<Column header="Status" sortable field="status" :filterMenuStyle="{ width: '14rem' }" style="min-width: 12rem">
<template #body="{ data }">
<Tag :value="data.status" :severity="getSeverity(data.status)" />
</template>
<template #filter="{ filterModel }">
<Dropdown v-model="filterModel.value" :options="statuses" placeholder="Select One" class="p-column-filter" showClear>
<template #option="slotProps">
<Tag :value="slotProps.option" :severity="getSeverity(slotProps.option)" />
</template>
</Dropdown>
</template>
</Column>
<Column field="activity" header="Activity" sortable :showFilterMatchModes="false" style="min-width: 12rem">
<template #body="{ data }">
<ProgressBar :value="data.activity" :showValue="false" style="height: 6px"></ProgressBar>
</template>
<template #filter="{ filterModel }">
<Slider v-model="filterModel.value" range class="m-3"></Slider>
<div class="flex align-items-center justify-content-between px-2">
<span>{{ filterModel.value ? filterModel.value[0] : 0 }}</span>
<span>{{ filterModel.value ? filterModel.value[1] : 100 }}</span>
</div>
</template>
</Column>
<Column headerStyle="width: 5rem; text-align: center" bodyStyle="text-align: center; overflow: visible">
<template #body>
<Button type="button" icon="pi pi-cog" rounded />
</template>
</Column>
</DataTable>
</div>
</DeferredDemo>
<DocSectionCode :code="code" :service="['CustomerService']" />
</template>
@ -628,12 +639,12 @@ const getSeverity = (status) => {
created() {
this.initFilters();
},
mounted() {
CustomerService.getCustomersLarge().then((data) => {
this.customers = this.getCustomers(data);
});
},
methods: {
loadDemoData() {
CustomerService.getCustomersLarge().then((data) => {
this.customers = this.getCustomers(data);
});
},
formatDate(value) {
return value.toLocaleDateString('en-US', {
day: '2-digit',