2

I have a list of items as a component:

Vue.component('building-list', {

    template: `<div><building v-for="building in buildings">{{ building.id }}</building></div>`,

    data() {

        return {

                buildings: {

                    'scavenger': { id: 'scavenger', name: "desh scavenger", amount_owned: 0, cost: 10, base_cps: 1, description: "A scavenger, specialising in the aquisition of Desh" },
                    'vaporator': { id: 'vaporator', name: "moisture farm", amount_owned: 0, cost: 50, base_cps: 2 },
                    'cantina': { id: 'cantina', name: "cantina", amount_owned: 0, cost: 650, base_cps: 3 },
                    'bazaar': { id: 'bazaar', name: "bazaar", amount_owned: 0, cost: 7800, base_cps: 4 },
                    'droidshop': { id: 'droidshop', name: "droid workshop", amount_owned: 0, cost: 80000, base_cps: 5 },
                    'bountyhunter': { id: 'bountyhunter', name: "bounty hunter guild", amount_owned: 0, cost: 140000, base_cps: 6 },
                    'kybermine': { id: 'kybermine', name: "kyber crystal mine", amount_owned: 0, cost: 250000, base_cps: 7 }

                }
        }

    }
        
});

and each of those items i want to look like this:

Vue.component('building', {

    template: `

        <div :key="building[id]" class="card" style="display: block;" v-on:click="buy_building(building[id])"> 
            <img :src="building[id]" style="cursor: pointer; width:100%; height:145px;">
            <div class="card-block">
                <h4 class="card-title">{{ building[name] }}</h4>
                <p class="card-text">cost: {{ building[cost] }}</p>
                <p class="card-text">owned: {{ building[amount_owned] }}</p>
            </div>
        </div>`

});

        <div class="container-fluid">

            <building-list></building-list>

        </div>

When I try to run this, I get this error for each item:

"Property or method "building" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties."

I am very new to Vue, so I followed the link to the documentation, however it doesn't really explain how to do this in this particular way, from the tutorials I have been following, this looks right, however again, those tutorials don't really explains things for this situation.

Is this even the right way of doing this?

1

1 Answer 1

4
  1. You must use props for pass data from parent component to child component.
  2. You can use 'dot notation' for access to object properties. If you want to get access with bracket notation you should write string like obj['property']. Read property accessors

Vue.component('building', {
  props: ['building'],
  template: `
        <div :key="building.id" class="card" style="display: block;" v-on:click="buy_building(building.id)">
            <div class="card-block">
                <h4 class="card-title">{{ building.name }}</h4>
                <p class="card-text">cost: {{ building.cost }}</p>
                <p class="card-text">owned: {{ building.amount_owned }}</p>
            </div>
        </div>
        `,
  methods: {
    buy_building(itemId) {
      alert(itemId);
    }
  }
});

new Vue({
  el: 'building-list',
  template: `<div><building v-for="item in buildings" :building='item' :key='item.id'></building></div>`,
  data() {

    return {

      buildings: {
        'scavenger': {
          id: 'scavenger',
          name: "desh scavenger",
          amount_owned: 0,
          cost: 10,
          base_cps: 1,
          description: "A scavenger, specialising in the aquisition of Desh"
        },
        'vaporator': {
          id: 'vaporator',
          name: "moisture farm",
          amount_owned: 0,
          cost: 50,
          base_cps: 2
        },
        'cantina': {
          id: 'cantina',
          name: "cantina",
          amount_owned: 0,
          cost: 650,
          base_cps: 3
        },
        'bazaar': {
          id: 'bazaar',
          name: "bazaar",
          amount_owned: 0,
          cost: 7800,
          base_cps: 4
        },
        'droidshop': {
          id: 'droidshop',
          name: "droid workshop",
          amount_owned: 0,
          cost: 80000,
          base_cps: 5
        },
        'bountyhunter': {
          id: 'bountyhunter',
          name: "bounty hunter guild",
          amount_owned: 0,
          cost: 140000,
          base_cps: 6
        },
        'kybermine': {
          id: 'kybermine',
          name: "kyber crystal mine",
          amount_owned: 0,
          cost: 250000,
          base_cps: 7
        }

      }
    }

  }

});
    .card {
      outline: 1px solid aquamarine;
      width: 200px;
    }
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<div class="container-fluid">
  <building-list></building-list>
</div>

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, that's exactly what I was looking for!
@Aaranihlus Welcome!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.