Comparison between VueJS's computed property and v-if for performance improvement

In my data array, each item has a specific state property with values of either allowed, pending, or rejected. The goal is to organize the data into separate sections based on their state, and each item also contains two buttons that can be used to change its state.

To achieve this separation, I utilize three computed properties:

computed: {
    pendingData() {
        return this.data.filter(x => x.state === 'pending')
    },
    allowedData() {
        return this.data.filter(x => x.state === 'allowed')
    },
    rejectedData() {
        return this.data.filter(x => x.state === 'rejected')
    }
}

The data is then displayed in distinct sections using v-for.

When it comes to changing the state of an item, an API call is made. To trigger this, the setState function is employed by passing the item's id and the new state:

<div class="state-change-buttons">
    <button @click="setState(item.id, 'allowed')">
        <span uk-icon="icon: check; ratio: 1.4"></span>
    </button>
    <button @click="setState(item.id, 'pending')">
        <span uk-icon="icon: future; ratio: 1.4"></span>
    </button>
</div>

This is how the setState function works:

setState(id, state) {
    const index = this.data.findIndex(x => x.id === id)
    this.$axios.post(`/api/${id}`, {state})
        .then(res => {
            this.data.splice(index, 1, res.data)
        })
        .catch(err => {
            this.$notify(err, 'danger')
        })
}

In order to update the data array in real-time, the findIndex method is used.

While the Vue style guide recommends avoiding v-if alongside v-for, especially for essential elements, the question arises whether efficiency should outweigh complexity in the app:

Current Setup:
3 computed properties (O(3n)) + findIndex (O(n)) + 3 v-for loops (O(p + r + q))

Conditional v-for:
3 conditional v-for loops (O(3n)) (omitting findIndex to directly pass index to setState)

Code snippet for conditional v-for:

<div v-for="(item, index) in data" v-if="item.state === 'pending'" :key="item.id">
    <!-- Data card body with buttons -->
</div>

<div v-for="(item, index) in data" v-if="item.state === 'allowed'" :key="item.id">
    <!-- Data card body with buttons -->
</div>

<div v-for="(item, index) in data" v-if="item.state === 'rejected'" :key="item.id">
    <!-- Data card body with buttons -->
</div>

Answer №1

There is some confusion regarding the relationship of v-if with either the parent or child element. This issue can be resolved by utilizing a template:

<template v-for="(item, index) in data">
  <div v-if="item.state === 'rejected'" :key="item.id">
    <!-- content for data card body (including buttons) -->
  </div>
</template>

Answer №2

Your question is incomplete without the proposed templates, so I can't provide a thorough answer. However, in situations like this, I prefer organizing data as an object for easy value retrieval and improved readability.

Here's how you can structure your code:

export default {
  name: 'list',
  data: () => ({
    data: {
      'id1': {id: 'id1', state: 'pending'},
      'id2': {id: 'id2', state: 'allowed'},
      'id3': {id: 'id3', state: 'rejected'},
    },
  }),
  computed: {
    dataList() {
      return Object.values(this.data)
    },
    pendingData() {
        return this.dataList.filter(x => x.state === 'pending')
    },
    allowedData() {
        return this.dataList.filter(x => x.state === 'allowed')
    },
    rejectedData() {
        return this.dataList.filter(x => x.state === 'rejected')
    },
  },
  methods: {
    setState(id, state) {
    this.$axios.post(`/api/${id}`, {state})
      .then(res => {
          Object.assign(this.data[id], res.data);
      })
      .catch(err => {
          this.$notify(err, 'danger')
      })
    }
  }
};

To display the data in the template:

<div v-for="item of pendingData" :key="item.id">
    <!-- data card body (including buttons) -->
</div>

<div v-for="item of  allowedData" :key="item.id">
    <!-- data card body (including buttons) -->
</div>

<div v-for="item of rejectedData" :key="item.id">
    <!-- data card body (including buttons) -->
</div>

By structuring the data this way, you eliminate the need for conditional rendering with v-if statements when iterating over different lists.

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

Tips on how to toggle/close a dropdown menu that is displayed on a different page using Vue

Below is a screenshot of my cart dropdown: https://i.sstatic.net/IdOZK.png The issue I am facing is that the cart stays open even when I navigate to another page. I need it to close when I move to a different page. Below is my component code: <template ...

Maintain a consistent header height with CSS even when using the calc() function

--dis: calc(var(--max-height) - var(--min-height)); /* @media large{--min-height:13rem}; @media small{--min-height:6.5rem}; --max-height:75vh; */ --percent: calc(var(--scroll-ani) / var(--dis)); /* in js: document.body.style = "--scroll-ani: ...

Tips for dynamically loading a different favicon with each page load in React

Is there a way to dynamically change the favicon on every page reload in React? I have a collection of icons and I want one to be randomly selected each time the page refreshes. The code for loading favicons in the manifest.json file is as follows: " ...

Using the fs module in a React Native application

Currently, I am facing a challenge in importing TinyDB into an expo project. The issue lies with fs, as Expo does not support it due to its third-party file system nature. I attempted using react-native-fs as an alternative but I am unsure about how to pr ...

The code line "npx create-react-app myapp" is not functioning as expected

When running the command 'npx create-react-app my-app', I encountered the following error message: Error: '"node"' is not recognized as an internal or external command, operable program or batch file. Before suggesting to cre ...

"Enhance the functionality of multiple elements with this innovative Jquery

Exploring the realm of Jquery plugins, I am faced with the challenge of making my plugin compatible with multiple elements. After scouring tutorials and various online forums, I've come to realize that plugin development is heavily dependent on the sp ...

Exploring the concept of recursive method calls in TypeScript

I am trying to call the filterArr method inside the filterArr itself. Here is my current implementation: function filterArr(array, search) { var result = []; array.forEach((a)=> { var temp = [], o = {}, ...

Efficiently submitting multiple forms in a single click

On my photo portfolio admin page, I have created a feature to caption, keyword, and credit each photo. Previously, I had multiple forms listed dynamically with submit buttons for each form. With over 20 photos/forms on the page, this process became tedious ...

Transferring checkbox status from HTML (JavaScript) to PHP

I am a beginner in JavaScript and I am trying to get the value from a variable in JS, send it via post (or ajax) to a PHP file, and display the text. However, I have attempted various methods but always encounter an undefined index error in PHP. Below is ...

The play() function is malfunctioning in Internet Explorer 11

I am having an issue with using the onclick function to call and play a file. The file plays fine in Chrome and Firefox, but not in ie11. Below is the code snippet: function play1(){ var audio1 = document.getElementById("audio1"); audio ...

Create a spectrum of vibrant colors depending on the numerical value

I'm attempting to create a function that generates rainbow colors based on a numerical value. var max = 10000; var min = 0; var val = 8890; function getColor(min, max, val) { // code to return color between red and black } Possible Colors: Re ...

The item image fails to load when Swiper is looped and using the next/prev buttons

I'm encountering an issue with swiper while trying to create a specific layout. This layout requires the first image to be larger than the others. Initially, I attempted to achieve this with a single slider but it caused miscalculations in the animati ...

Cross-origin resource sharing in Express.js servers

Encountering a minor issue with the connection setup between my Express.js API and React client. The Express API is running on http://localhost:3001, while React is hosted at http://exampleip:3000 (both on the same Windows server). To address Cross-Origi ...

After submitting the form, I must only deactivate the checkbox that has been selected

Here is the HTML code I am working with: I have multiple checkboxes designed as buttons to select a room, but it's quite annoying when they all get selected at once. $("form").submit(function() { $('.seat input:checkbox').prop("disable ...

Secondary Electron window not properly receiving IPC messages

While developing my TypeScript code that is linked to the HTML being executed by my application, I encountered an issue with creating a new window for my settings. It seems that the preloaded script is loaded onto the new window upon opening, but the windo ...

ACL - Utilize ACL in conjunction with the passport authentication system

I am experimenting with node_acl in combination with passport-local. Unfortunately, I am facing an issue when trying to secure the route for the admin-user '/admin', as it keeps redirecting me to the /login page. Below is a simplified version of ...

Looking for an improved, tidier, or more efficient alternative to PHP Random Text?

Is there a more efficient way to generate random text other than using the random_text function in PHP? I'm interested in a method that is quick to render and light on server resources for faster page loading. Should I consider alternatives like Javas ...

Is it advisable to compress my API response in PHP?

At this stage, I find myself needing to generate extensive reports in order to gain a better understanding of the data at hand. To do so, I must retrieve one of my tables which contains around 50 parameters and 40,000 rows. While fetching the data via API ...

What is the process for extracting a single hashtag using the Twitter API with JSON in JavaScript?

Currently, I am utilizing the npm package 'twit' in conjunction with node js to interact with the Twitter API. My goal is to retrieve the hashtags used by a specific user in their most recent tweets. By employing the following code snippet, I ca ...

Is @babel the solution to transpile Array.prototype.flat?

I accidentally caused a backward compatibility issue in my React application by utilizing Array.prototype.flat. I was quite surprised that this problem persisted even after transpiling - I had assumed it would generate es2015-compatible code. Is there a w ...