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

Is there a way to determine if a website is utilizing javascript?

Currently, I am in the process of developing a web scraping tool using beautifulsoup. Some of the websites I am targeting contain JavaScript elements that prevent me from using urllib3 efficiently. As a workaround, I have incorporated selenium into my sc ...

Execute another Ajax request using jQuery after the first Ajax callback has been completed

Looking for a solution to ensure the correct order of appended contents loaded via ajax, I have the following script: $.get('http://mydomain.com/ajax1.php/', function(data){ var data_one = $(data).find('#ajax_editor_suggestion_c ...

Leveraging the Wikia API

I've been attempting to utilize the X-men API on Wikia in order to gather the name and image of each character for use in a single page application using JavaScript. You can find the link to the wiki page here: Despite my efforts, I am struggling to ...

Executing one specific test in Protractor using Selenium

How can I execute a single test in Protractor with Selenium? describe('Login page', function() { beforeEach(function() { browser.ignoreSynchronization = true; ptor = protractor.getInstance(); }); it('should contain navigation items&ap ...

Express 4 Alert: Headers cannot be modified once they have been sent

I recently upgraded to version 4 of Express while setting up a basic chat system. However, I encountered an error message that says: info - socket.io started Express server listening on port 3000 GET / 304 790.443 ms - - Error: Can't set headers ...

The MongoDB .push operation is returning a null value

Take a look at the GitHub repository where I am actively working: https://github.com/Stick-z/first-media-app I'm currently in the process of creating a website and focusing on the backend development. One of my tasks involves setting up a jokes array ...

Utilizing asynchronous functions to assign a JSON dataset to a variable

Having an issue here! I've created a function to retrieve data from a local JSON file on my server. The problem is that the data is returned asynchronously, so when I try to set it to a variable for later use, it always ends up being undefined. I don& ...

Issue with displaying ng-repeat data in AngularJS tbody

I am experiencing an issue with using ng-repeat inside a tbody element. Here is the code snippet that is causing trouble: <tbody> <tr ng-repeat="group in groups"> <td>{{ group.name }}</td> </tr> </tbody> Wh ...

Creating a paragraph from text inputs using React

I'm currently working on code that retrieves input from two textboxes - one for a string value and one for a number value. I want this data to be displayed in real-time within a paragraph without the need for a submit button. I've been struggling ...

Having trouble integrating VueX store and router into Mocha tests

Latest Update To view the issue on VueX git repository that has been created, please follow this link: https://github.com/vuejs/vuex/issues/1509 If you want to replicate the problem, here is the link to the repository: https://github.com/djam90/vuex-vue- ...

What could be causing my Angular Ngrx app's state not to render properly on the application?

Is there a way to automatically render the state when the app loads without having to click a button? I am currently facing an issue where the state is empty until I manually trigger the click function by pressing a button. I have tried using this.store.se ...

Manipulating strings within strings with JavaScript

It's been a strange discovery I made while working with JavaScript. Whenever I try to assign a two-word string to a CSS property, like setting the fontFamily property of an HTML element to "Arial Black", it ends up looking something like thi ...

What is the best way to incorporate JavaScript in a repeater?

I am currently working on an asp.net project that involves using a repeater. <asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1"> <HeaderTemplate> <asp:label ID="lblexp" runat="server" Text="05/11/1 ...

Show several fresh windows

Greetings everyone. Let me explain my current situation: I have a search page where users can select a product from a drop-down list, and upon clicking a button, a gridview is displayed showing the specifications of the selected product. What I'm a ...

Exploring a section of a react-chartjs Pie chart

I'm currently exploring how to create a static Pie chart using react-chartjs-2. Wanting to make one slice stand out more than the others, I aim to have it appear larger: My focus is on accessing a specific slice in the pie chart and adjusting its out ...

Utilizing database information to dynamically select Nightwatch.js tests for execution

Currently, I am in the process of configuring nightwatch tests for a specific website. The setup involves assigning testing personas to run tests, which works smoothly in our development environment. However, we face an issue when we need to dynamically ad ...

What could be causing the mousewheel event in my code to remain active?

Whenever I try to scroll on Google Chrome, an error occurs on my website. jquery-3.3.1.min.js:2 [Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See To resolve this issue: $(document).ready(f ...

Generating an array in Javascript using JSON

I've been doing a lot of research, but I can't seem to find a solution that works for me. My goal is to retrieve the next four bus arrival times for a specific bus stop using an application that reaches out to an API returning JSON data. The issu ...

Using the ui-router to repeatedly call an AngualrJS directive

I've encountered an issue with my HTML audio player in AngularJS. When the page is refreshed, everything works perfectly - I can set the source and play audio without any problems. However, if I navigate to another state in the app and then try to loa ...

Tips for configuring Webstorm to automatically change double quotes to single quotes when reformatting source code

After using cmd + alt + l in Webstorm to format my JavaScript code, I noticed that double quotes are used instead of single quotes. How can I configure Webstorm to automatically change the double quotes to single quotes in my code? ...