Karolis Tička
Karolis Tička

Reputation: 254

Children to children communication

My component is pretty big so I will give you simplified example, maybe someone will know how to solve my problem.

I have invoice component with children components like 'subtotal', 'vat_subtotal', 'total' (it's example). I'm using v-ref to get direct access to every child from invoice component. Also, subtotal is calculated from invoice properties, then vat_subtotal is calculated from subtotal children properties. And 'total' is calculated from vat_subtotal children.

Example:

invoice.$refs.subtotal.total = {some calculations}
vat_subtotal.total = @$parent.$refs.subtotal.total * 1.21
total.total = @$parent.$refs.vat_subtotal.total

The problem is that i'm getting warnings when page loads, be cause 'total' children is trying to access 'vat_total' children properties, but @$parent.$refs.vat_total is still 'undefined' (I don't know why. When later im changing something in form, it reacts normaly and recalculate everything right). It seems, that one children is trying to compute properties while other children isn't loaded yet.

Upvotes: 0

Views: 327

Answers (2)

pkawiak
pkawiak

Reputation: 1329

The way you are trying to solve things is technically possible but highly discouraged. As stated in the docs:

Although it’s possible to access any instance in the parent chain, you should avoid directly relying on parent data in a child component and prefer passing data down explicitly using props. In addition, it is a very bad idea to mutate parent state from a child component, because:

  1. It makes the parent and child tightly coupled;

  2. It makes the parent state much harder to reason about when looking at it alone, because its state may be modified by any child! Ideally, only a component itself should be allowed to modify its own state.

In general, you should aim for creating a model representing the state of your application. Instead of accessing parents / children directly, pass any relevant data down to children using props. Children can notify their parent about changes using events, or you can use .sync binding to synchronize models automatically.

I think that you would benefit from reading about more structured approach to Vue application architecture. I'd start with Flux-inspired Application Architecture for Vue.js.

Upvotes: 2

Roy J
Roy J

Reputation: 43881

Don't reach into a child for data. If the parent needs access (in your case, to give access to another child), the data item should be created in the parent and passed as a prop to the child. That is how data can be shared among multiple children. Child components should not depend on other child components being available through the parent (or on anything in the parent, really, if it isn't passed in as a prop).

If the child component is responsible for changing the prop value, you can pass it using .sync.

Upvotes: 3

Related Questions