1

How could a child component pass its value to the parent component? Here is my child component:

Javascript:

new Vue({
  el: '#table-list',
  data: {
    tableList: ['Empty!'],
    tableSelected: ""
  },
  methods: {
    getTableList() {
      axios
        .get('/tables')
        .then(tableList => {
          this.tableList = tableList.data;
        })
        .catch(e => console.warn('Failed to fetch table list'));
    },
    selectTable(table) {
      this.tableSelected = table;
    }
  },
  mounted() {
    this.getTableList();
  }
});

HTML:

<div id="table-list">
    <p v-for="table in tableList">
        <i class="fa fa-table" aria-hidden="true"></i>&nbsp;
        <span class="text-primary" v-on:click="selectTable(table)"> {{ table }} </span>
    </p>
</div>

When on click, selectTable is called, I want to show the value in its parent component? i.e I need to pass tableSelected property to the parent component. How could I do this?

Roman
  • 4,922
  • 3
  • 22
  • 31
Suhail Gupta
  • 22,386
  • 64
  • 200
  • 328
  • 1
    Possible duplicate of [vuejs update parent data from child component](https://stackoverflow.com/questions/40915436/vuejs-update-parent-data-from-child-component) – thanksd Aug 21 '17 at 12:56

2 Answers2

2

You should use vue components, specifically events mechanism for what you want to archive.

Props are for pass data from parent to a child components, and events to send messages from child component to parent.

We have learned that the parent can pass data down to the child using props, but how do we communicate back to the parent when something happens? This is where Vue’s custom event system comes in.

Please see this fiddle https://jsfiddle.net/AldoRomo88/sLo1zx5b/

I have changed your selectTable method to emit a custom event

selectTable: function(table) {
  this.$emit('item-changed',table);
}

And in your parent component you just need to listen for that event

<div>
{{selectedItem}}
</div>

<table-list @item-changed="newValue => selectedItem = newValue " ></table-list>

Let me know if you need more clarification.

tony19
  • 125,647
  • 18
  • 229
  • 307
AldoRomo88
  • 2,056
  • 1
  • 17
  • 23
  • I did not understand the `@item-changed` part. The child emits `item-changed` event. How are we catching this in the parent? – Suhail Gupta Aug 21 '17 at 13:13
  • `@item-changed` is a short form for `v-on:item-changed` please see this updated fiddle, it is using `v-on` syntax and also using a method on parent instead of updating value directly. https://jsfiddle.net/AldoRomo88/sLo1zx5b/1/ – AldoRomo88 Aug 21 '17 at 13:24
  • Is there a way to share variables between different components? What if there isn't a parent-child relationship? – Suhail Gupta Aug 21 '17 at 14:20
  • Absolutely you can share variables between components. Children have access to all a parent's data via this.$root.$data, and if there's no parent-child relationship, you still have the global (window) scope. Provide the same global variable to 2 different Vue instances and they will be sharing data. See my answer. You need to understand why this can be a trap, but that doesn't mean don't do it. – bbsimonbb Aug 21 '17 at 22:36
0

Here is the page that explains how children emit events to listening parents.

Here is the page on managing state.

Remember what you're aiming for, with VUE, is MVVM. You want all your state in a store, where each item of state is stored once, regardless of how many times it's referenced, and how many ways it can be updated.

Your tableSelected is an item of state. You can pass state changes up the chain if you need to, so long as they finish in a store, not in a component or a vue. But you can keep it simple: make tableSelected a property in your store, and declare it directly in the data element of components that need it. If you want to be rigorous, put a changeTableSelected() method on the store.

You need to start worrying about props and events if one component will have many instances, or if a component knows nothing about the page on which it will appear. Until that time, I would prefer using data and the store.

tony19
  • 125,647
  • 18
  • 229
  • 307
bbsimonbb
  • 27,056
  • 15
  • 80
  • 110