2
votes

Can someone help me share data between vue.js components? For example, I have a Table component that contains two components: a button and an input box. When I click on the button component, I want it to return data of the row it is in, including data in the input component. Right now, I am able to click the button and have it return the row data, except what's inside of its sibling input component. Does anyone have any idea how I can do this? Here's my fiddle to demonstrate what i've achieved so far and what I'm trying to do

Below is the relevant code and here is my jsfiddle that also includes my HTML: https://jsfiddle.net/rfy7sqzf/2/

My parent Table component:

Vue.component('my_table', {
  template: '#my_table',
  props: {
    data: Array,
    columns: Array,
    actions: Array
  }
});

My two sibling components (button1 and input)

const button1 = Vue.extend({
  template:'<button class="btn btn-primary" @click="view">View</button>',
  methods: {
    view: function () {
      console.log('--row data--', this.row_data)
    }
  },
  props: ['row_data']
})

const input = Vue.extend({
  template:'<input type="text" />'
})

My main Vue app:

var vm = new Vue({
  el: '#el',
  data: {
      actions: [
        {
          name: 'view',
          label: 'View Company',
          tmpl: button1
        },
        {
          name: 'qty',
          label: 'Quantity',
          tmpl: input
        },
      ],
      companies: [
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
        {
          company_name: 'abc',
          company_email: 'some_email',
          company_phone_number: '###',
        },
      ],
      columns: [
        {
          field: 'company_name',
          label: 'Company',
        },
        {
          field: 'company_email',
          label: ' Email'
        },
        {
          field: 'company_phone_number',
          label: 'Phone #'
        },
      ],
  },
});

Note - I understand that I could totally do this by putting data in the parent's data object & passing the data as props, but this would only work if I had a minimal # of child/sibling components..

Thanks in advance!

2
This is a perfect use case for a flux-style architecture. I highly recommend you check out Vuex, the official VueJS flux-style state library. - David L

2 Answers

1
votes

This is how I make tables (with actions) — http://jsfiddle.net/jonataswalker/qgjgkud8/

Basically you will make use of Scoped Slots.

Some code:

  <vue-table :fields="fields" :rows="rows">
    <template slot="actions" scope="props">
      <my-button title="View" @click.native="view(props.row)"></my-button>
      <my-button title="Edit" @click.native="edit(props.row)"></my-button>
      <my-button title="Delete" @click.native="remove(props.row)"></my-button>
    </template>
  </vue-table>
1
votes

A more robust and scalable way to achieve this is by using a store, all the data that needs to be shared between components should reside in a central store, and then every component can get or set this data.

You might need initially to spend an hour or so to get familiar with the concept, but then it will be very useful in the long run.

Learn Vue store here: Vuex