0

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>

2
  • 1
    You are creating 4000 elements. That will be slow in any framework. Commented Jun 17, 2020 at 17:10
  • in jquery, I have used different approaches and it's working perfectly fine. Commented Jun 17, 2020 at 17:16

2 Answers 2

1

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];
            }
        }
    })
Sign up to request clarification or add additional context in comments.

1 Comment

its working but only thing your code is returning only one row. i need a table
0

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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.