Mastering data binding with Vue Js is a process that requires dedication and time

I'm a Vue JS beginner and I've created a component that repeats a grid-like section. However, I've noticed that adding a dropdown in the grid is causing a significant increase in load time. As the number of records grows, the load time will only get worse. I am in search of a solution to decrease the page load time. Here is a snippet from 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>
            

Answer №1

If you need to create a large number of select elements with multiple options, the following code snippet can help achieve this without relying on any specific library. The runtime is comparable to using VueJS.

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);
    }
}

Another approach could be letting users choose from the 4000 sales available before making their selections. Check out the CodePen for an example.

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];
            }
        }
    })

Answer №2

Through extensive research and development, I have discovered a solution using Vuetify in Vue.js that works wonders. I tested it with 50,000 rows and it rendered in just 4 seconds. You can push the data limit up to 500,000 rows, and it will still only take about 10 seconds for rendering. The current complexity for rendering the data is at 50,000 * 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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8ff9faeacfbda1f7">[email protected]</a>/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="32444757465b544b72001c4a">[email protected]</a>/dist/vuetify.js"></script>
<link href="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="314744544558574871031f49">[email protected]</a>/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/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4d2b2222390d7e6335">[email protected]</a>/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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Performing an AJAX GET request to the API after a set time interval

The API is constantly updating with live values, so I am attempting to fetch the data every second and display it on the webpage. Although I used a GET request call every N seconds using set_interval(), the values only load once and do not update with eac ...

Leveraging multer for handling a FormData object in a node.js server

Having trouble with an HTML form that includes two buttons among other text input areas. The front-end javascript code is set up to handle the submit action by creating a FormData object to store the file and sending it via a jQuery AJAX request to a node. ...

Update the value of a scope variable directly within a controller. Subsequently making a function call

Hey there, I just want to start by saying sorry in case this question has already been asked or if it seems silly. I'm pretty new to AngularJS and have managed to overcome CORS errors, set up login via Parse, and even created an API for my app using ...

Swapping out a code snippet within an HTML document using JavaScript

As a new member of this community, I present to you my very first problem that needs solving. It might be a piece of cake for some of you, but for me, it's proving to be quite tricky. The task at hand involves replacing or removing a string to make ev ...

Looking to arrange an object by the value of a nested object in Typescript/Angular?

I'm currently developing an Angular 9 application focused on covid-19 cases, and I need to arrange my objects by the value of nested objects. Here is the dataset that I want to organize alphabetically based on the 'state' field values: stat ...

Is there a way to have dynamic content from angularJS show up in an iframe?

When working with tabular content generated using ng-repeat in AngularJS, it is important to find a way to display this content within an iframe. The goal is to allow users to drag and resize the content as needed. However, using the iframe src attribute ...

Tips on aligning a v-btn alongside v-expansion-panels on the same row

Struggling with aligning my layout. Trying to get a single set of v-expansion-panels and a v-btn in the same row, both visually centered within a card. I managed to almost achieve it in this codepen: https://codepen.io/anzuj/pen/PoPPbdw with the following ...

Can anyone provide guidance on adjusting the color of the axes on a c3 chart within a Vue environment

I am struggling to change the axis color of my c3 chart in a Vue app where I have successfully built the chart using c3.js. The issue is not just limited to the axis color; I find it difficult to customize any style on the c3 charts, which is quite frustr ...

One issue with my Quiz app is that sometimes the correct and incorrect answer methods run concurrently, leading to occasional occurrences of this problem

One issue I encountered while developing a Quiz app is that sometimes the methods for correct and incorrect answers run simultaneously. This problem occurs sporadically. I want to highlight that my code is functioning correctly. The only challenge I face ...

Is it the browser's responsibility to convert ES6 to ES5 internally?

Given the support for ES6 in modern browsers, do they internally convert ES6 to ES5 before executing the code? Or can they process ES6 natively using a C++ engine? If they are able to run ES6 directly, how do they guarantee that executing ES6 code produce ...

How can I effectively set up and utilize distinct npm modules on my local environment?

A React Native component I have created lives in a separate folder with its own package.json file, and now I want to use it in another project. The component named MyComponent is located in Workspace/MyComponent and has specific dependencies listed in its ...

Establish an interval that loops through the elements of an array

I'm currently working on implementing an interval for the length of an array stored in state. The particular array eventDate consists of 4 elements, and I want the function to cycle through values 0, 1, 2, 3, then loop back to 0. This is my code ...

How to Resolve ENOENT ERROR When Using fs.unlink in an Express.js Simple Application?

Currently, I am developing a basic blog using express.js. For managing the posts, I have opted for Typicode/lowdb as my database. The posts are created, updated, and deleted based on unique IDs stored in a data.json file. Additionally, I utilize the slug d ...

Pair two arrays based on a specific key value

I'm currently facing a challenge where I need to associate two arrays of objects, and I could really use some help with this. Explanation : One array contains various reference products const array1 = [ {name: peanuts, referenceKey: 0}, {name: almon ...

Dynamic CSS Changes in AngularJS Animations

I am currently working on a multi-stage web form using AngularJS. You can see an example of this form in action by visiting the link below: http://codepen.io/kwakwak/full/kvEig When clicking the "Next" button, the form slides to the right smoothly. Howev ...

Modifying the file name during the download process using AngularJS

Looking for a solution to download a file from an ajax GET request in angularjs? Currently, I am using an invisible iframe to trigger the "Save as" popup for the downloaded file. However, I need to change the name of the file before the popup appears. If ...

I am experiencing an issue where the custom form validation directive in AngularJS is not functioning properly within my modal

To enhance the validation of my input boxes, I created a custom directive called nx-validate. This directive is designed to be added to a bootstrap div.form-group, which will then check if the <input/> field is $dirty or $invalid, and apply the appro ...

Customize YouTube iframe styles in Angular 4+ with TypeScript

Has anyone been successful in overriding the style of an embedded YouTube iframe using Angular 4+ with TypeScript? I've attempted to override a CSS class of the embed iframe, but have not had any luck. Here is the URL to YouTube's stylesheet: ...

Why does Vue 3 template display 101 instead of 1 when incrementing the number from 0?

Vue.createApp({ data() { return { counter: 0 } }, template: '<div>{{counter++}}</div>' }).mount('#root') Ultimately, the code above displays the number 101 on the page. Any insights into why this is happ ...

How can serverless platforms handle binary data such as PDF files?

I am currently experiencing an issue that involves uploading a PDF file in Vue.js to a serverless Node.js application, resulting in broken file content. This problem occurs due to the serverless platform incorrectly parsing binary data types. How can I e ...