Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Vue Directive Execution Order: v-if Versus v-for

Tech 1

In Vue.js, v-if manages conditional rendering based on expression truthiness. Conversely, v-for iterates over data sources to generate multiple DOM elements. Optimizing list rendering requires assigning a unique key property to each item, enabling the Diff algorithm to track node identity efficiently.

Compilation Behavior and Precedence

Both directives are processed during the template-to-render-function phase. When placed on the same element, execution order matters significantly for performance.

Consider an implementation where both directives coexist on a single tag:

<div id="root">
  <p v-if="showTasks" v-for="task in taskList">
    {{ task.name }}
  </p>
</div>

With associated reactive state:

new Vue({
  el: '#root',
  data() {
    return {
      showTasks: true,
      taskList: [
        { name: 'Alpha' },
        { name: 'Beta' }
      ]
    }
  }
})

Inspecting the compiled render function reveals that v-for (represented internally as _l) processes before the conditional check (.render). The logic effectively becomes an iteration containing an inner condition:

function anonymous() {
  with (this) {
    return _c('div', [
      _l((taskList), (t) => 
        (showTasks) ? _c('p', [t.name]) : _e()
      )
    ])
  }
}

This structure confirms that the loop executes first, followed by the condition evaluation for every item, which is inefficient.

Alternative Structure

To prioritize condition checking, apply v-if to a wrapper container instead of the list item:

<template v-if="showTasks">
  <li v-for="task in taskList" :key="task.id">{{ task.name }}</li>
</template>

The resulting compilation logic shifts the conditional checkoutside the iteration scope:

function anonymous() {
  with (this) {
    return (showTasks) ? (
      _l((taskList), (t) => _c('li', [t.name]))
    ) : _e()
  }
}

Source analysis indicates that directive processing checks for attributes before if attributes within the generation pipeline.

Optimization Strategies

  1. Separate Directives: Never bind v-if and v-for directly to the same element. This forces a full iteration regardless of visibility state.
  2. Wrapper Tag Usage: Utilize <template> or another structural parent for conditional wrapping. The template does not render physical DOM nodes but acts as a logical block for instructions.
  3. Computed Filtering: If filtering depends on list properties, manipulate the data source via computed properties rather than template directives:
computed: {
  filteredTasks() {
    return this.allData.filter(t => t.isVisible === true)
  }
}

Then use the computed result in the loop:

<li v-for="task in filteredTasks" :key="task.id">
  {{ task.name }}
</li>

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.