#vue #javascript #frontend

Day 3: Logic & Control Flow

Welcome to Day 3! Now that we have data, we need to control when and how it is displayed.

Conditional Rendering: v-if vs v-show

v-if, v-else-if, v-else

These directives physically add or remove elements from the DOM.

<script setup lang="ts">
import { ref } from 'vue'

const status = ref('success') // try 'error' or 'loading'
</script>

<template>
  <div v-if="status === 'loading'">Loading...</div>
  <div v-else-if="status === 'error'">Something went wrong!</div>
  <div v-else>Data loaded successfully!</div>
</template>

v-show

This toggles the CSS display: none property. The element always exists in the DOM.

<h1 v-show="isVisible">I am just hidden, not gone!</h1>

Rule of Thumb: default to v-if. Use v-show only if you need to toggle something very frequently (like a dropdown menu or animation target) to save on DOM manipulation costs.

List Rendering: v-for

To render a list of items, we use v-for. The syntax is item in items.

<script setup lang="ts">
import { ref } from 'vue'

const fruits = ref(['Apple', 'Banana', 'Cherry'])

const users = ref([
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
])
</script>

<template>
  <ul>
    <!-- Using index -->
    <li v-for="(fruit, index) in fruits" :key="index">
      {{ index + 1 }}. {{ fruit }}
    </li>
  </ul>

  <div class="user-list">
    <!-- Component loop -->
    <div v-for="user in users" :key="user.id">
      User: {{ user.name }}
    </div>
  </div>
</template>

The Importance of :key

You MUST provide a unique :key attribute. This hints to Vue’s internal algorithm which elements can be reused vs re-ordered.

  • Bad: :key="index" (if the list order can change)
  • Good: :key="item.id" (unique ID from DB)

Challenge for Day 3

  1. Create a list of todos ({ id: number, text: string, done: boolean }).
  2. Render them using v-for.
  3. Add a button “Hide Completed”.
  4. If “Hide Completed” is on, use v-if to hide the completed tasks.

Solution:

<script setup lang="ts">
import { ref, computed } from 'vue'

const hideCompleted = ref(false)
const todos = ref([
  { id: 1, text: 'Learn Vue', done: true },
  { id: 2, text: 'Build an app', done: false },
  { id: 3, text: 'Profit', done: false },
])
</script>

<template>
  <button @click="hideCompleted = !hideCompleted">
    {{ hideCompleted ? 'Show All' : 'Hide Completed' }}
  </button>

  <ul>
    <li v-for="todo in todos" :key="todo.id">
      <!-- Logic in template is okay for simple things -->
      <span v-if="!hideCompleted || !todo.done">
        {{ todo.text }} {{ todo.done ? '✅' : '⏳' }}
      </span>
    </li>
  </ul>
</template>

Great job! You can now handle lists and conditionals. Tomorrow, we tackle User Interaction—specifically handling forms and inputs.