0
votes

I need to collect data from all child components and get it in Parent component. For example i have a form component with "Save" button. Once i click on "Save" button i need all child component send me all data that an user put there.

<Form>
  <Name />
  <DatePicker />
  .....
</Form> 

So the main component is Form and it has several child components. Once i click on "Save" in i need to get child components data in Form.

I am thinking about giving "ref" to all child component and call their own methods in Parent once i click on "Save" inside Form. In those methods i will collect all data and fire events with this.$emit there i can send to parent the data i have collected.

Is that a good solution?

Or maybe better to use EventBus?

1
I wrote a related article a few minutes ago. You need the child components to $emit their changes to the parent component: dev.to/valentinprgnd/…Valentin
I see. So the main point is this.$watch and using it we follow the changes and notify parent about that.Denys
But my case is a bit complex. I need to get info from child components only when i click on "Save" button in parent component. So child components should not pass any data until parent tells them about itDenys
Do you have a Form component in whose slot you give other components, e.g. Name, DatePicker, and you want the data from these subcomponents to go to this Form after pressing Save? Using multiple Form components with different subcomponents results in separate data sets in each Form?Gander
I don't use slots. I have 1 form parent component with 7 child components inside. And yes, after pressing "Save" in Form component i need to get all data from all child components inside Form component....Denys

1 Answers

0
votes

I prefer bind over emit.

Vue.component("InputField", {
  template: `<input v-model="syncedValue" />`,
  name: "InputField",
  props: {
    value: String
  },
  computed: {
    syncedValue: {
      get() {
        return this.value;
      },
      set(v) {
        this.$emit("input", v);
      }
    }
  }
});

Vue.component("Form", {
  template: `<div><InputField v-model="name"/><InputField v-model="surname"/><button @click="save">Save</button></div>`,
  name: "Form",
  data() {
    return {
      name: "",
      surname: ""
    };
  },
  methods: {
    save() {
      alert(`${this.name} ${this.surname}`);
    }
  }
});

new Vue({
  template: `<Form></Form>`
}).$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>