Reputation: 3922
I am new to Vue JS. So I just made one component which is repeating a section like a grid. but my problem is when I add dropdown in a grid it is taking too much time. Records may be increased next time then load time will also increase so I am looking for a solution so page load time will decrease. Here is a sample which I am using in my code.
var obj = [];
for (var i = 0; i < 4000; i++) {
var subobj = [];
for (var j = 0; j < 100; j++) {
subobj.push({
id: j,
name: 'mukesh'
})
}
var newobj = {
'Year': 2018,
'Month': 01,
'Sale': 512,
drp: subobj,
name: "negi"
}
obj.push(newobj);
}
new Vue({
el: "#tableDemo",
data: {
sales: obj
}
})
<script src="https://npmcdn.com/vue/dist/vue.js"></script>
<div id="tableDemo">
<table class="table table-striped">
<thead>
<tr>
<th>Month</th>
<th>Sale</th>
<th>Customer</th>
<th>Customer</th>
<th>Customer</th>
</tr>
</thead>
<tbody>
<tr v-for="(sale,i) in sales" :key="i">
<th scope="row">{{ sale.Month }}</th>
<td>{{ sale.Sale }}</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
</tr>
</tbody>
</table>
<label class="control control--checkbox">
First checkbox
<input type="checkbox" checked="checked" />
<div class="control__indicator"></div>
</label>
</div>
Upvotes: 0
Views: 485
Reputation: 3922
Hi After doing lots of R&D I found one solution. i.e. vuetify in Vue js. It's working like a Charm. I have added 50000 rows and it's rendering in 4 sec. you can increase data up to 500000 and it will hardly take 10 sec. As you can see current complexity to render a data is 50000* 300
"use strict";
var d = new Vue({
el: '#app',
vuetify: new Vuetify(),
data: function data() {
return {
items: [],
drpItems: [],
itemsPerPage: 0,
optionsLength: 6,
loading: true,
footerProps: {
'items-per-page-options': [10, 20, 50, 100, 1000]
},
headers: [{
text: 'ID',
value: 'id'
}, {
text: 'Description',
value: 'description'
}, {
text: 'QTY1',
value: 'qty1'
}, {
text: 'QTY2',
value: 'qty2'
}, {
text: 'Qty3',
value: 'qty3'
}],
customer: {
name: 'customer',
items: []
}
};
},
created: function created() {
this.initialize();
var self = this;
window.onresize = function (event) {
self.updateTable();
};
},
methods: {
updateTable: function updateTable() {
var tableHeight = document.getElementById('dataTable').offsetHeight;
this.itemsPerPage = parseInt(tableHeight / 40);
if (this.customer.items.length < this.itemsPerPage) this.itemsPerPage = this.customer.items.length;
if (!this.footerProps['items-per-page-options'].includes(this.itemsPerPage)) {
if (this.footerProps['items-per-page-options'].length == this.optionsLength) {
this.footerProps['items-per-page-options'].unshift(this.itemsPerPage);
} else {
this.footerProps['items-per-page-options'].shift();
this.footerProps['items-per-page-options'].unshift(this.itemsPerPage);
}
}
},
initialize: function initialize() {
var self=this;
for (var i = 0; i < 300; i++) {
this.drpItems.push("mukesh" + i);
}
for (var i = 0; i < 50000; i++) {
var obj = {
id: i,
description: 'ABC',
qty1: '',
qty2: 'mukesh14',
qty3: 'mukesh1'
};
obj.drpItems = [];
this.customer.items.push(obj);
} // deep copy is the solution
// const items = JSON.parse(JSON.stringify(this.customer.items))
this.items = this.customer.items;
setTimeout(function(){ self.loading=false;},1500);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" type="text/css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" type="text/css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" type="text/css" rel="stylesheet" />
<style>
#dataTable .v-table tbody tr:not(:last-child) {
border-bottom: none;
}
#dataTable th{
font-size:16px;
color:"black"
}
.v-data-table__wrapper{
border:1px solid;
}
</style>
<v-data-table
must-sort
:headers="headers"
:pagination.sync="pagination"
:rows-per-page-items="pagination.rowsPerPageItems"
:total-items="pagination.totalItems"
:loading="loading"
:items="items"
class="elevation-1"
>
<div id="app">
<div>
<v-app>
<v-main>
<v-container>
<v-data-table id="dataTable" dense
:headers="headers"
:items="items"
:rows-per-page="itemsPerPage"
:footer-props="footerProps"
:loading="loading" loading-text="Loading... Please wait"
>
</template>
<template v-slot:item.qty1="props">
<v-text-field v-model="props.item.qty1"></v-text-field>
</template>
<template v-slot:item.qty2="props">
<v-select
:items="drpItems"
label="Standard"
v-model="props.item.qty2"
:value="props.item.qty2"
></v-select>
</template>
<template v-slot:item.qty3="props">
<v-select
:items="drpItems"
label="Standard"
:value="props.item.qty3"
v-model="props.item.qty3"></v-select>
</template>
</v-data-table>
</v-container>
</v-main>
</v-app>
</div>
</div>
Upvotes: 0
Reputation: 177
You are creating 4000*3 select elements with 100 option elements each. Consider the following code which is library agnostic. It has a comparable runtime to the posted VueJS code.
for(let i = 0; i < 4000 * 3; i++){
let select = document.createElement("select");
document.body.appendChild(select);
for(let j = 0; j < 100; j++){
let option = document.createElement("option");
option.text="mukesh";
select.add(option);
}
}
An alternative would be to let the user select which of the 4000 sales they wanted first and then allow the user to make the selections. CodePen
HTML
<div id="tableDemo">
<select v-model="selected_sale">
<option v-for="(sale,i) in sales" :key="i">
{{i}}
</option>
</select>
{{selected_sale}}
<table class="table table-striped">
<thead>
<tr>
<th>Month</th>
<th>Sale</th>
<th>Customer</th>
<th>Customer</th>
<th>Customer</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">{{ sale.Month }}</th>
<td>{{ sale.Sale }}</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
<td>
<select v-model="sale.name">
<option value="--Selected--">--Select--</option>
<option v-for="d in sale.drp" :value="d.name">{{d.name}}</option>
</select>
</td>
</tr>
</tbody>
</table>
<label class="control control--checkbox">
First checkbox
<input type="checkbox" checked="checked" />
<div class="control__indicator"></div>
</label>
</div>
JS
let start = Date.now();
var obj = [];
for (var i = 0; i < 4000; i++) {
var subobj = [];
for (var j = 0; j < 100; j++) {
subobj.push({
id: j,
name: 'mukesh'+j
})
}
var newobj = {
'Year': 2018,
'Month': i,
'Sale': 512,
drp: subobj,
name: "negi"
}
obj.push(newobj);
}
let end = Date.now();
console.log(end - start);
new Vue({
el: "#tableDemo",
data: {
sales: obj,
selected_sale:0,
},
computed:{
sale(){
return this.sales[+this.selected_sale];
}
}
})
Upvotes: 1