VueJS Zoom in/out performance lags - vue.js

I am creating a web app which has a lot of tables that get rendered on the page, however I have noticed the performance of the web page reduces drastically the more I add. Especially when i zoom in and out, this causing the page to lag for a few seconds. Is there any way to work around this? I have heard lazy loading is a good method, however that seems like its only for initial loads.
<v-text-subtitle name="moaamlol6" class="blue--text"
>Mapping of Assessment Against Module Learning Outcomes - Level
6</v-text-subtitle
>
<v-dialog
v-model="dialogL6"
fullscreen
hide-overlay
transition="dialog-bottom-transition"
>
<template v-slot:activator="{ on, attrs }">
<v-btn
color="red lighten-2"
dark
v-bind="attrs"
v-on="on"
outlined
>
Edit
</v-btn>
</template>
<v-card>
<v-toolbar dark color="primary">
<v-toolbar-title
>Mapping of Assessment Against Module Learning Outcomes -
Level 6</v-toolbar-title
>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn text dark #click="dialogL6 = false"> Cancel </v-btn>
<v-divider vertical></v-divider>
<v-btn dark text #click="generateL6"> Insert </v-btn>
</v-toolbar-items>
</v-toolbar>
<v-card-text style="display: inline-flex">
<div>
<table class="bordered" ref="L6">
<tr>
<th colspan="99">
Mapping of Assessment Against Module Learning Outcomes -
Level 6
</th>
</tr>
<tr>
<th rowspan="2">Module Assessment Elements</th>
<th colspan="99">Module Learning Outcomes</th>
</tr>
<tr>
<td v-for="index in numOfCLO" v-bind:key="index">
{{ index }}
</td>
</tr>
<tr v-for="y in specMod.length" v-bind:key="y">
<td>{{ specMod[y - 1].module_name }}</td>
<td
class="notclicked"
v-for="x in numOfCLO"
v-bind:key="x"
:id="x + '*' + y"
#click="changeClassL6(x, y)"
></td>
</tr>
</table>
</div>
<div>
<p v-html="courseDataJson[0].mapping_assessment_l6"></p>
</div>
</v-card-text>
</v-card>
</v-dialog>
<p
v-html="courseDataJson[0].mapping_assessment_l6"
v-if="dialogL6 == false"
></p>
I have 4x of these tables, however the performance is fine. But once I add the final table the performance tanks
<v-text-subtitle name="isfa" class="blue--text"
>Indicative Schedule for Assessment</v-text-subtitle
>
<table class="bordered" ref="indicative">
<tr>
<th colspan="99">Indicative Schedule for Assessment</th>
</tr>
<tr>
<th>Week</th>
<td>Level 3</td>
<td>Level 4</td>
<td>Level 5</td>
<td>Level 6</td>
<td>Level 7</td>
</tr>
<tr>
<th>TT</th>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr v-for="x in 52" :key="x">
<th>Week {{ x }}</th>
<td
v-for="y in 5"
:key="y"
#click="openDialog(x, y)"
class="clickable"
>
<div v-for="data in schedule_dataJson" v-bind:key="data.id">
<v-card
v-if="data.week == x && data.level == y + 2 && data.courseId == courseDataJson[0].id"
class="mt-2 mb-2"
color="#F5F5F5"
>
<v-toolbar :color="data.colour">
<v-toolbar-title>
<v-icon>{{ data.icon }}</v-icon> {{ data.name }} |
{{ data.location }}
</v-toolbar-title>
</v-toolbar>
<v-card-text v-if="data.note != null">
{{ data.note }}
</v-card-text>
</v-card>
</div>
</td>
</tr>
</table>
<v-dialog
v-model="dialog"
width="500"
height="1000"
persistent
transition="scale-transition"
>
<v-card>
<v-toolbar color="blue">
<v-toolbar-title>
Enter Schedule - Week {{ week }} - Level {{ level + 2 }}
</v-toolbar-title>
</v-toolbar>
<v-card-text
><v-select label="Icon" :items="items" v-model="icon">
<template slot="item" slot-scope="data">
<v-icon>{{ data.item }}</v-icon>
</template>
<template slot="selection" slot-scope="data">
<v-icon>{{ data.item }}</v-icon>
</template>
</v-select></v-card-text
>
<v-card-text
><v-text-field label="Select Name" v-model="name"></v-text-field
></v-card-text>
<v-card-text
>Select Colour:
{{ colour }}
<v-color-picker
class="ma-2"
dot-size="30"
v-model="colour"
:swatches="swatches"
show-swatches
hide-canvas
disabled
hide-inputs
></v-color-picker
></v-card-text>
<v-card-text
><v-text-field
label="Select Location"
v-model="location"
></v-text-field
></v-card-text>
<v-card-text>
<v-textarea auto-grow outlined label="Notes" v-model="note">
</v-textarea>
</v-card-text>
<v-divider></v-divider>
<v-card-subtitle
><v-btn text color="primary" #click="dialog2 = true"
>Existing Events</v-btn
></v-card-subtitle
>
<v-dialog
v-model="dialog2"
transition="slide-y-transition"
width="500"
height="1000"
persistent
>
<v-card>
<v-card-title class="pink lighten-2">
Delete Existing Events
</v-card-title>
<div v-for="data in schedule_dataJson" v-bind:key="data.test">
<v-toolbar
:color="data.colour"
v-if="data.week == week && data.level == level + 2"
>
<v-toolbar-title>
{{ data.name }} |
<v-icon>{{ data.icon }} | {{ data.id }} </v-icon>
</v-toolbar-title>
<v-spacer></v-spacer>
<v-toolbar-items>
<v-btn icon #click="deleted(data.id)"
><v-icon>mdi-delete</v-icon></v-btn
>
</v-toolbar-items>
</v-toolbar>
</div>
<v-divider></v-divider>
<v-card-actions>
<v-btn #click="dialog2 = false">close</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
<v-divider></v-divider>
<v-card-actions>
<v-btn #click="dialog = false" color="primary" text
>Cancel</v-btn
>
<v-btn #click="insert" color="primary" text>Insert</v-btn>
</v-card-actions>
</v-card>
</v-dialog>

Related

Grouping datatable with vuetify

with vuetify 2.x, I´d like to show my data grouped with option to collapse and expand on icon click.
My problem is if I use both 'group.header slot' and 'group slot', the first one doesn´t appear in the table.
If I hide 'group.header' slot I can put the group name into 'group slot', but I can´t use the icon click to collapse/expand the group.
<v-card-text>
<v-data-table
:headers="headers_parcelas"
:items="fitens_parcelas"
:items-per-page="5"
dense
hide-default-header
group-by="nome_conta"
show-group-by
class="elevation-1 marcarguias"
>
<template #[`group.header`]="{ group, isOpen, toggle }">
<th colspan="2">
<v-icon #click="toggle"
>{{ isOpen ? 'mdi-minus' : 'mdi-plus' }}
</v-icon>
{{ group }}
</th>
</template>
<template #group="props">
<!-- <span class="font-weight-bold">
{{ props.group }}
</span> -->
<v-data-table
:headers="props.headers"
:items="props.items"
dense
item-key="nome_conta"
hide-default-footer
>
<template #body="{ items }">
<tbody>
<tr v-for="item in items" :key="item.id">
<td>{{ item.descricao }}</td>
<td>{{ item.nome_forma_recebimento }}</td>
<td>{{ item.nome_quem_lancou }}</td>
<td>
{{ formatCurrency(item.valor_recebido) }}
</td>
<td class="text-center">
<span>
<v-icon
small
title="Apagar Movimento"
color="error"
#click.stop="deleteParcelaCaixa(item)"
>
mdi-delete
</v-icon>
</span>
</td>
</tr>
<tr>
<td colspan="5" class="text-center">
<span class="ml-10 font-weight-black">
SubTotal: {{ formatCurrency(itemTotal(items)) }}
</span>
</td>
</tr>
</tbody>
</template>
</v-data-table>
</template>
<template #[`body.append`]="{ items }">
<v-col
cols="12"
sm="6"
class="text-center font-weight-black text-h6 primary mx-auto"
>
Total:{{ formatCurrency(getTotalCost(items)) }}
</v-col>
</template>
</v-data-table>
</v-card-text>```

Vuetify 3 : v-menu location property not working

i have a v-menu on toolbars right corner. The menu displays as bottom right (end) so half the card is outside the view. I want to change to bottom left (start) however i can't seem to make it work.
<v-menu
location="start"
rounded
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>
I'm missing somethings? im checking the example in the docs https://next.vuetifyjs.com/en/components/menus/
thanks
edit: added screenshots of current behaviour vs expected
Edit 2: I tried the v-menu on a codepen and works as intended, however for some reason, it does not work inside a v-app-bar
Try using prop "anchor" instead of "location".
<v-menu
anchor="bottom end"
rounded
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>
I can't even tell you why this could work, because I wasn't able to find it in the Docs or Files, but it is used like that in one of the templates I'm using.
However, this only works for large screens, on mobile the card will be outside the view again.
I had the same problem, the solution is using the activator prop or perhaps, in your case you sould use the internal-activator prop.
<v-menu
location="start"
rounded
internal-activator
>
<template v-slot:activator="{ props }">
<v-btn
icon
v-bind="props"
>
<v-avatar
color="brown"
size="large"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
</v-btn>
</template>
<v-card>
<v-card-text>
<div class="mx-auto text-center">
<v-avatar
color="brown"
>
<span class="white--text text-h5">{{ user.initials }}</span>
</v-avatar>
<h3>{{ user.fullName }}</h3>
<p class="text-caption mt-1">
{{ user.email }}
</p>
<v-divider class="my-3"></v-divider>
<v-btn
rounded
variant="text"
#click="() => goSettings() "
>
Settings
</v-btn>
<v-divider class="my-3"></v-divider>
<v-btn
#click="() => logOut()"
>
Disconnect
</v-btn>
</div>
</v-card-text>
</v-card>
</v-menu>

V-Data-Table 1.5 to 2.0

I'm updating vuetify to the lastest version ( was 1.5 prior ) and I'm having trouble trying to adjust my table with the new props and slots. You can see my table right below, it has the possibility of selecting multiple lines and select all as well at the same time. I just need to purely replicate what I have, only to the new version and I don't know how to do it with the new slots.
<div class="col-12">
<v-data-table
v-model="selected"
:headers="headers"
:items="queriedData"
item-key="Id"
select-all
:pagination.sync="pagination"
:total-items="queriedData.lenght"
prev-icon="mdi-menu-left"
next-icon="mdi-menu-right"
sort-icon="mdi-menu-down"
>
<template v-slot:headers="props">
<tr>
<th v-if="canView">
<v-checkbox
:input-value="props.all"
:indeterminate="props.indeterminate"
primary
hide-details
color="white"
#click.stop="toggleAll"
class="table-checkbox-header"
></v-checkbox>
</th>
<th width="30px">
</th>
<th width="30px">
</th>
<th
v-for="header in props.headers"
:key="header.text"
:class="['column sortable', pagination.descending ? 'desc' : 'asc', header.value === pagination.sortBy ? 'active' : '']"
#click="changeSort(header.value)"
>
{{ header.text }}
<v-icon small>arrow_upward</v-icon>
</th>
</tr>
</template>
<template v-slot:no-data>
<div class="text-center">
{{NoInformation}}
</div>
</template>
<template v-slot:items="props">
<td v-if="canView">
<v-checkbox
v-model="props.selected"
primary
color="primary"
hide-details
class="table-checkbox-body"
></v-checkbox>
</td>
<td style="display: inline-flex;" >
<v-tooltip top color="primary" v-if="CanEdit">
<template v-slot:activator="{ on }">
<a v-on="on" class="btn-table-icon" #click.prevent="doSomething(props.item.Id)">
<i class="mdi mdi-eye icons-tables-margins"></i>
</a>
</template>
<span>{{view}}</span>
</v-tooltip>
<v-tooltip top color="primary" v-if="CanEdit" >
<template v-slot:activator="{ on }">
<a v-on="on" class="btn-table-icon" #click.prevent="doSomething(props.item.Id)">
<i class="mdi mdi-square-edit-outline icons-tables-margins"></i>
</a>
</template>
<span>{{view}}</span>
</v-tooltip>
</td>
<td>
<div v-if="props.item.Id!=0">
<span>Hello</span>
</div>
<div v-else>
<i class="mdi mdi-folder-lock-open"></i>
</div>
</td>
<td>{{ props.item.Name}}</td>
<td>{{ props.item.Name2}}</td>
<td>{{ props.item.Name3}}</td>
<td>{{ props.item.Name4}}</td>
<td :style="'color:' + props.item.ColorName" >{{ props.item.Name5}}</td>
</template>
</v-data-table>
</div>
Thank you.
Using slots seems not very different with the new version.
The only difference I can see is the props:
Before :
<template v-slot:headers="props">
Now :
<template v-slot:headers="{props}">
And for the checkboxes, you can just use the prop 'show-select' instead of using slots

Why the card hover is out from the container?

The problem is when I hover the cursor to the card the hover card are out from the main container which avoid me to click the navigation bar.
I have try to put inside the v-content and v-container but still not working.
<template>
<div>
<br>
<br>
<br>
<v-container grid-list-md>
<v-layout row wrap>
<v-flex xs6 md4 sm4 lg3 xl2 v-for="n in 12" :key="n" class="pa-2">
<v-hover>
<v-card
slot-scope="{ hover }"
:class="`elevation-${hover ? 12 : 2}`"
class="max-w-sm rounded overflow-hidden shadow-lg"
>
<v-img
src="https://www.candere.com/media/catalog/product/cache/1/thumbnail/9df78eab33525d08d6e5fb8d27136e95/g/r/gr00237_1_2.jpg"
>
<v-chip class="ma-2" small color="#e5af57" text-color="black">916</v-chip>
</v-img>
<v-card-text>
<table style="width:100%">
<tr>
<td colspan="2">
<h4 class="text-sm-center">Bunga Emas Arau</h4>
</td>
<br>
</tr>
<tr>
<td colspan="2">
<v-divider></v-divider>
</td>
<br>
</tr>
<tr class="font-weight-small">
<td>Weight Approx.</td>
<td>2.37 g +/-</td>
</tr>
<tr class="font-weight-medium">
<td>Price</td>
<td>RM300-2300</td>
</tr>
</table>
</v-card-text>
<v-fade-transition>
<v-overlay v-if="hover" absolute color="#190033">
<v-btn color="#d19f4e">See more info</v-btn>
</v-overlay>
</v-fade-transition>
</v-card>
</v-hover>
</v-flex>
</v-layout>
</v-container>
</div>
</template>
I want the hover to stay inside and doesn't interrupt the main navigation bar.
Try to add z-index="0" to <v-overlay></v-overlay>.
new Vue({
el: "#app"
});
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#3.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-container grid-list-md>
<v-layout row wrap>
<v-flex xs6 md4 sm4 lg3 xl2 v-for="n in 12" :key="n" class="pa-2">
<v-hover>
<v-card slot-scope="{ hover }" :class="`elevation-${hover ? 12 : 2}`" class="max-w-sm rounded overflow-hidden shadow-lg">
<v-img src="https://www.candere.com/media/catalog/product/cache/1/thumbnail/9df78eab33525d08d6e5fb8d27136e95/g/r/gr00237_1_2.jpg">
<v-chip class="ma-2" small color="#e5af57" text-color="black">916</v-chip>
</v-img>
<v-card-text>
<table style="width:100%">
<tr>
<td colspan="2">
<h4 class="text-sm-center">Bunga Emas Arau</h4>
</td>
<br>
</tr>
<tr>
<td colspan="2">
<v-divider></v-divider>
</td>
<br>
</tr>
<tr class="font-weight-small">
<td>Weight Approx.</td>
<td>2.37 g +/-</td>
</tr>
<tr class="font-weight-medium">
<td>Price</td>
<td>RM300-2300</td>
</tr>
</table>
</v-card-text>
<v-fade-transition>
<v-overlay v-if="hover" absolute color="#190033" z-index="0">
<v-btn color="#d19f4e">See more info</v-btn>
</v-overlay>
</v-fade-transition>
</v-card>
</v-hover>
</v-flex>
</v-layout>
</v-container>
</div>
This is probably a z-index problem for the v-overlay element. Try lowering the z-index prop for the v-overlay.

Horizontal alignment in <v-data-table> from Vuetify

I have the following table in which I can't align some items such as the checkbox and the actions:
This is the table:
<v-data-table
:headers="headers"
:items="users"
hide-actions
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td>{{ props.item.email }}</td>
<td class="text-xs-left">{{ props.item.empresa.descripcion}}</td>
<v-checkbox disabled v-model="props.item.isAdmin"></v-checkbox>
<td class="text-xs-left">{{ props.item.createdAt }}</td>
<td class="justify-center layout px-0">
<v-icon
small
class="mr-2"
#click="editItem(props.item)"
>
Editar
</v-icon>
<v-icon
small
left
class="mr-2"
#click="deleteItem(props.item)"
>
Eliminar
</v-icon>
</td>
</template>
</v-data-table>
I need to align the v-checkbox and the v-icon.
There is no css in the <style> section.
Give it a try wrapping the <v-layout justify-center></v-layout> with <td></td> like the Ohgodwhy comment.
It would be like:
<v-data-table
:headers="headers"
:items="users"
hide-actions
class="elevation-1"
>
<template slot="items" slot-scope="props">
<td>
<v-layout justify-center>
{{ props.item.email }}
</v-layout>
</td>
<td>
<v-layout justify-center>
{{ props.item.empresa.descripcion}}
</v-layout>
</td>
<td>
<v-layout justify-center>
<v-checkbox disabled v-model="props.item.isAdmin"></v-checkbox>
</v-layout>
</td>
<td>
<v-layout justify-center>
{{ props.item.createdAt }}
</v-layout>
</td>
<td>
<v-layout justify-center>
<v-icon
small
class="mr-2"
#click="editItem(props.item)"
>
Editar
</v-icon>
<v-icon
small
left
class="mr-2"
#click="deleteItem(props.item)"
>
Eliminar
</v-icon>
</v-layout>
</td>
</template>
</v-data-table>
For those of you taking a simple example from the Vuetify docs like I did:
<v-card>
<v-card-title id="balloon-title">Balloon Info - tracking [balloon ID]</v-card-title>
<v-data-table disable-sort dense hide-default-footer :headers="headers" :items="info" item-key="name">
</v-data-table>
</v-card>
The solution above requires you to change your entire layout. Instead, I styled the td selector like so
td {
text-align: center !important;
}
Hope this helps!
edit- make sure this style isn't in a scoped component.
Here's a simplified snippet that iterates <td> instead of specifying each prop, using only the css class text-center instead of a whole v-layout component:
<v-data-table
item-key="yourItemKey"
:items="dataSet"
:headers="headers">
<!-- item is the row itself with the column values -->
<template v-slot:item="{ item }">
<tr>
<td v-for="(val, key) in item" :key="key" class="text-center">
{{ val }}
</td>
</tr>
</template>
</v-data-table>