Home > front end >  Cannot dynamically pass a prop to a component within a v-for loop in Vue js
Cannot dynamically pass a prop to a component within a v-for loop in Vue js

Time:07-20

I have an array sheets initialised in data, has an item pushed to it when a button is pressed

data() {
    return {
        sheets: []
    };
}

And in the html I'm trying to add a Card component for each element in this array and pass the data as a prop, but none of the components get rendered and there is no error message. I also tried putting the v-for directly on the component but it has the same result

<div id="sheets">
    <template v-for="c in sheets">
        <Card :info="c"/>
    </template>
</div>

Meanwhile if I do something like this, it displays all the data in the array correctly, so I dont understand whats going wrong here

<div id="sheets">
    <template v-for="c in sheets">
        <span>{{c}}</span>
    </template>
</div>

--

Solution In my component the data from prop was being manipulated in the created() function, it works after I did this in the mounted() function instead

CodePudding user response:

Make sure you have following things done correctly:

  1. Imported your Card component
  2. Passing and accessing the props
  3. There are no conflicts in the variable names and id names

Next thing you need to know and is a must while using v-for is adding :key to the element which acts as unique id and lets Vue detect that each element is unique inside the v-for. One thing to be noted while using :key is that, you cannot use :key on the <template> tag.

Adding a validation using v-if would be a good idea, so v-for only executes if the array is not empty.

<div id="sheets">
    <template v-if="sheets.length">
        <Card v-for="(sheet,index) in sheets" :key="index" :info="sheet" />
    </template>
</div>

Edit 1: As mentioned by Michal in the comments section that using index can lead to difficulties while debugging issues. You can use either :key="sheet" or if sheet is object including some unique id in it, then use :key="sheet.id" and get rid of the index

// use this if sheet is not an object
<div id="sheets">
    <template v-if="sheets.length">
        <Card v-for="sheet in sheets" :key="sheet" :info="sheet" />
    </template>
</div>

OR

// use this if sheet is an object having some unique id in it
<div id="sheets">
    <template v-if="sheets.length">
        <Card v-for="sheet in sheets" :key="sheet.id" :info="sheet" />
    </template>
</div>

CodePudding user response:

As :key is not mandatory, It should work without that as well. I just created a working fiddle below. Please have a look and try to find out the root cause.

Vue.component('card', {
  props: ['info'],
  template: '<span>{{ info }}</span>',
});

var app = new Vue({
  el: '#app',
  data: {
        sheets: [],
      count: 0
  },
  methods: {
    create() {
      this.count  ;
        this.sheets.push('Sheet'   this.count);
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <button @click="create">Create a Card!</button>
  <template v-for="c in sheets">
    <Card :info="c"></Card>
  </template>
</div>

  • Related