Ren
Ren

Reputation: 171

How can I dynamically render an array passed as a prop in vue.js?

I am trying to pass this data to a component in vue. I can get the data in the child component, and can render the array, or access each object properties by calling products[0].name, but I am looking to render each object separately in a v-for loop. please help!!

parent component:

<template>
  <div>
    <h1>Welcome To Our Shop</h1>
    <div class="products">
      <div v-for="product in products" v-bind:key="product.name">
        <div><ShopItem v-bind:products="products" /></div>
      </div>
    </div>
  </div>
</template>

<script>
import ShopItem from "../components/Shop/ShopItem";
export default {
  name: "Shop",
  components: { ShopItem },
  data() {
    return {
      products: [
        {
          name: "Basic Deck",
          price: 7,
          description:
            "The Basic Deck includes 68 cards: 10 cards in each of six categories, three icon legend cards, five blank cards for developing your own backstory elements, and instructions.",
          image: require("@/assets/Draeorc.png"),
        },
        {
          name: "Card Bundle",
          price: 10,
          description:
            "The Card Bundle includes the Basic Deck, Technical Booster, Mystical Booster and instructions as a single self-printable PDF.",
          image: require("@/assets/Twilight.png"),
        },
        {
          name: "Full Bundle with Box",
          price: 12,
          description:
            "The Full Bundle includes the Basic Deck, Technical Booster, Mystical Booster, instructions and tuck box as a single self-printable PDF.",
          image: require("@/assets/Orig_Godbringer.png"),
        },
      ],
    };
  },
};
</script>

child component:

<template>
  <div class="product-container">
    <div>
      <h2>{{ products[0].name }}</h2> //this is where I want to call on the name
      <div class="card-container">
        <img src="../../assets/Draeorc.png" alt="cards" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ShopItem",
  props: ["products"],
};
</script>

Upvotes: 2

Views: 2638

Answers (2)

Owl
Owl

Reputation: 6853

Change

v-bind:products="products"

to

v-bind:products="product"

since you are using for-of loop

and on child component, change:

products[0].name

to

products.name

and since the property is an object, not an array, it's better to change your property name to product instead of products

So you will have this on parent component:

<div v-for="product in products" v-bind:key="product.name">
    <div><ShopItem :product="product" /></div>
    // :product is a shorthand for v-bind:product
</div>

and this on child component:

<template>
  <div class="product-container">
    <div>
      <h2>{{ product.name }}</h2> //this is where I want to call on the name
      <div class="card-container">
        <img src="../../assets/Draeorc.png" alt="cards" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "ShopItem",
  props: ["product"],
};
</script>

Upvotes: 1

Kick Buttowski
Kick Buttowski

Reputation: 6739

Here

  <div v-for="product in products" v-bind:key="product.name">
    <div><ShopItem v-bind:products="products" /></div>
  </div>

your code does not make sense why?

because you want to go through the array which is here products and show each item inside the products array. When you go through the array, an item which is right for that iteration will be passed to ShopItem component and no need to access index by using
products[index]

so it is better to do the following

<div><ShopItem v-bind:product="product" /></div>

Therefore, your ShopItem component will have access to a product one at the time when it goes through the v-for loop

Upvotes: 2

Related Questions