1

I need to create two components who share data. I making a item lists and item cart who add or delete the specified items.

HTML:

<script>
  var food_menu = '[{"cat":"Burgers","name":"Hamburger classic","text":"200g of meat with chips","price":"9,50"},{"cat":"Burgers","name":"Hamburger chili","text":"250g of meat with chips + drink (orange juice 0,5l)","price":"12,50"},{"cat":"Burgers","name":"Chickenburger","text":"250g of meat with chips + drink (orange juice 0,5l)","price":"10,50"},{"cat":"Burgers","name":"Chickenburger chili","text":"250g of meat with chips + drink (orange juice 0,5l)","price":"14,50"},{"cat":"Steaks","name":"Baconburger","text":"300g of meat with chips","price":"16,50"},{"cat":"Steaks","name":"Hotburger","text":"300g of meat with chips + drink (orange juice 0,5l)","price":"18,50"},{"cat":"Maxs","name":"Hotburger max","text":"450g of meat with chips","price":"21,50"},{"cat":"Maxs","name":"Chickenburger max","text":"450g of meat with chips","price":"15,50"}]';

</script>

<body>
  <main>
      <cart></cart>
      <food :menu="menu"></food>
  </main>
  <script src="https://unpkg.com/vue"></script>
</body>

The cart component:

const cart = Vue.component('cart', {
  template: `
    <div>
      <pre>{{$data}}</pre>
    </div>
  `,
  data() {
    return {
      items: []
    }
  },
  created() {
    this.$parent.$on("añadir", (item, index) => {
    alert('asdasd')
      if (typeof this.items[index] === "undefined") {
        this.items[index] = item;
        this.items[index].quantity = 1;
      } else {
        this.items[index].quantity++;
      }
    });
  }
});

The item list component (It Works)

const food = Vue.component('food', {
  props: ['menu'],
  template: `
      <div>
        <div class="food-item" v-bind:class="item.cat" v-for="(item,index) in menu">
          <h3>{{item.name}}</h3>
          <a class="add-cart" v-on:click="addToCart(item, index)">Añadir al carro</a>
          <p>{{item.text}}</p>
          <span>{{item.price}}€</span>
        </div>
    </div>
  `,
  methods: {
    addToCart(item, index) {
      this.$parent.$emit('añadir', item, index);
    }
  }
});

And the separated instances:

new Vue({
    el: 'main',
    data: {
      menu: JSON.parse(food_menu)
    },
    components: {
      'food': food,
      'cart': cart
    }
  });

When i try to modify "items" it doesnt change the template.

https://jsfiddle.net/50l3r/wu0gjz2r/6/

5
  • 1
    You might want to try using events instead of letting children mess with the items array directly. Commented Oct 14, 2017 at 13:29
  • I dont understand u Commented Oct 14, 2017 at 16:19
  • vuejs.org/v2/guide/… Commented Oct 14, 2017 at 17:17
  • @hayavuk i updated the code Commented Oct 20, 2017 at 18:17
  • I've played with your code a little, and I see what the problem is. First of all it's not this.$parent.$emit, but just this.$emit. Secondly, since the items and the cart are unrelated, one cannot trap events from the other. You should either put the items inside the cart component (e.g., using slots, etc), or you should learn how to use Vuex. Commented Oct 20, 2017 at 18:34

1 Answer 1

1

i find the problem posting on vue forums: https://forum.vuejs.org/t/vue-component-data-doesnt-update/20086

Problem caused because i can't modify array like this:

this.items[index] = newValue
this.items.length = newLength

I need to use:

Vue.set(this.items, index, newValue)

or

this.items.push()
this.items.splice()

Link to docs: https://v2.vuejs.org/v2/guide/list.html#Caveats

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.