v-memo & v-once

Preview — 3 of 10 questions

When should you use v-show instead of v-if?

javascript
<template>
  <!-- v-if: destroys/recreates the tree on each toggle -->
  <!-- Good for: rarely toggled elements, expensive child components when hidden -->
  <HeavyChart v-if="isChartVisible" :data="data" />
  <!-- HeavyChart is NOT mounted when isChartVisible is false  saves memory -->

  <!-- v-show: always rendered, CSS toggle only -->
  <!-- Good for: frequently toggled elements (tabs, dropdowns, tooltips) -->
  <div v-show="isDropdownOpen" class="dropdown-menu">
    <ul><!-- menu items --></ul>
  </div>
  <!-- dropdown-menu is always in DOM, just display: none when closed -->
</template>

<!-- Performance comparison:
  v-if: Initial render fast (nothing rendered), toggle slow (mount/unmount)
  v-show: Initial render includes everything, toggle is instant (CSS only)
-->
AAlways use v-show — it's faster than v-if in all cases
BUse v-show only for CSS animations; use v-if for all other conditional rendering
CUse v-show for elements that toggle frequently; use v-if for elements that are rarely shown or have complex child trees
Dv-show and v-if are identical — the choice is purely stylistic

What is the purpose of the key attribute in v-for loops?

javascript
<template>
  <!--  Without key  Vue reuses DOM nodes in-place -->
  <div v-for="item in items">{{ item.name }}</div>

  <!--  Using index as key  breaks with reordering or deletion -->
  <div v-for="(item, index) in items" :key="index">{{ item.name }}</div>

  <!--  Stable unique ID as key  Vue can track each item correctly -->
  <div v-for="item in items" :key="item.id">{{ item.name }}</div>

  <!--  For components with internal state  correct key ensures state matches item -->
  <TodoItem
    v-for="todo in todos"
    :key="todo.id"
    :todo="todo"
  />
</template>
AIt is required by the browser to identify list items for accessibility
BIt prevents the list from re-rendering when other components update
CIt helps Vue's Virtual DOM algorithm efficiently identify which items changed, were added, or removed
DIt enables CSS animations on list items automatically

Why should you use computed properties instead of methods for derived data in templates?

javascript
<script setup>
import { ref, computed } from 'vue'

const items = ref([/* 10,000 items */])
const filterText = ref('')

// ❌ Method — runs on EVERY render, even unrelated ones
function filteredItemsMethod() {
  console.log('Method: running expensive filter...')
  return items.value.filter(i => i.name.includes(filterText.value))
}

// ✅ Computed — runs ONLY when items or filterText changes
const filteredItems = computed(() => {
  console.log('Computed: running expensive filter...')
  return items.value.filter(i => i.name.includes(filterText.value))
})

const unrelatedCount = ref(0)
// When unrelatedCount changes:
// - filteredItemsMethod() runs again (wasted work)
// - filteredItems does NOT re-run (cache hit)
</script>

<template>
  <!-- Both look identical in template usage -->
  <div v-for="item in filteredItems" :key="item.id">{{ item.name }}</div>
  <!-- vs -->
  <div v-for="item in filteredItemsMethod()" :key="item.id">{{ item.name }}</div>
</template>
AComputed properties run faster because they use Web Workers internally
BComputed properties are cached based on reactive dependencies — they only re-run when dependencies change
CMethods in templates are not supported — computed is the only option
DComputed properties work with TypeScript; methods do not

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.