Vue.js v-for: Creating Dynamic Components with Props

Example 1. Generating Component Elements with v-for

Let's start by creating a basic Vue.js application that generates component elements using the v-for directive. In this example, we'll have a simple App.vue file and a FoodItem.vue component.

App.vue

<template>
  <h1>Food</h1>
  <p>Components created with v-for based on an array.</p>
  <div id="wrapper">
    <food-item
      v-for="foodName in foods"
      :key="foodName"
      :food-name="foodName"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      foods: ['Apples', 'Pizza', 'Rice', 'Fish', 'Cake'],
    };
  },
};
</script>

FoodItem.vue

<template>
  <div>
    <h2>{{ foodName }}</h2>
  </div>
</template>

<script>
export default {
  props: ['foodName'],
};
</script>

In this example, we use v-for to iterate over the foods array in App.vue, dynamically creating food-item components based on the array values.

Example 2. Utilizing Shorthand v-bind

To dynamically bind props in Vue.js, we often use v-bind. In this example, we'll leverage the shorthand : to bind props more efficiently.

App.vue

<template>
  <!-- ... (unchanged code) ... -->
  <food-item
    v-for="foodName in foods"
    :key="foodName"
    :food-name="foodName"
  />
</template>

This shorthand notation enhances readability and is commonly used in Vue.js projects.

Example 3. Addressing the Importance of the key Attribute

When using v-for to generate dynamic elements, Vue.js relies on the key attribute to differentiate between elements and optimize performance. Let's examine an example where the absence of the key attribute leads to unexpected behavior.

App.vue

<!-- ... (unchanged code) ... -->
<button @click="removeItem">Remove Item</button>
export default {
  // ... (unchanged code) ...
  methods: {
    removeItem() {
      this.foods.splice(1, 1);
    },
  },
};

In this scenario, when an item is removed, Vue.js may incorrectly reuse elements. To fix this, we introduce the key attribute:

App.vue

<food-item
  v-for="food in foods"
  :key="food.name"
  :food-name="food.name"
/>

By using a unique identifier the key, we ensure proper element differentiation and prevent unexpected behavior.

Example 4. Creating a Dynamic Food Page

Let's enhance our example by creating a dynamic food page. We'll modify App.vue to include descriptions, favorite statuses, and a button to toggle favorites.

App.vue

<template>
  <h1>Food</h1>
  <p>Food items are generated with v-for from the 'foods' array.</p>
  <div id="wrapper">
    <food-item
      v-for="food in foods"
      :key="food.name"
      :food-name="food.name"
      :food-desc="food.desc"
      :is-favorite="food.favorite"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      foods: [
        { name: 'Apples', desc: 'Apples are a type of fruit.', favorite: true },
        { name: 'Pizza', desc: 'Pizza has a bread base with toppings.', favorite: false },
        { name: 'Rice', desc: 'Rice is a type of grain that people like to eat.', favorite: false },
        // ... (more food items)
      ],
    };
  },
};
</script>

<style>
  /* ... (unchanged styles) ... */
</style>

FoodItem.vue

<template>
  <div>
    <h2>
      {{ foodName }}
      <img src="/img_quality.svg" v-show="foodIsFavorite">
    </h2>
    <p>{{ foodDesc }}</p>
    <button @click="toggleFavorite">Favorite</button>
  </div>
</template>

<script>
export default {
  props: ['foodName', 'foodDesc', 'isFavorite'],
  data() {
    return {
      foodIsFavorite: this.isFavorite,
    };
  },
  methods: {
    toggleFavorite() {
      this.foodIsFavorite = !this.foodIsFavorite;
    },
  },
};
</script>

<style>
  /* ... (unchanged styles) ... */
</style>

In this final example, each food item includes a description, a favorite status, and a button to toggle the favorite status. This demonstrates the dynamic nature of Vue.js components created with v-for. The use of v-for in conjunction with Vue.js components opens up a world of possibilities for creating dynamic and interactive user interfaces. Through the provided examples, we've explored the foundational concepts of dynamically generating components, binding props efficiently using shorthand notations and addressing key considerations such as the key attribute to ensure accurate rendering and prevent unexpected behavior. As you continue your journey with Vue.js, it's essential to experiment with these concepts and build upon them to create more complex and feature-rich applications. The ability to dynamically generate components based on data arrays, coupled with the versatility of props, empowers developers to create scalable and maintainable user interfaces.

Remember to explore additional features and functionalities offered by Vue.js, as it is a robust framework with a vibrant ecosystem. Whether you're building simple dynamic lists or intricate user interfaces, Vue.js provides the tools and flexibility to bring your web applications to life. As you delve deeper into Vue.js, consider exploring advanced features, state management with Vuex, and integrating Vue Router for seamless navigation within your applications. By combining these elements, you'll be well-equipped to tackle a wide range of web development challenges and create engaging and responsive user experiences.

Sharing 3 exercises that are designed to reinforce your understanding. See the attachment.