This article assumes you have basic knowledge of Vue & Vue’s reactive system.

Emergencies are a given, and sometimes we get one of those when building frontend applications, thankfully most of these frontend frameworks provide us with multiple ways to handle emergencies. With Vue, one of the many emergency hatches is the $ref attribute.

Generally, it’s common to have a ref attribute on pure HTML elements (like the <input /> element) in Vue, in the same way, you can have a reference on a custom component as well (<my-custom-componet />), and have access to its computed values, methods, data properties, and so on. This, however, should only be used in emergency situations or as a last resort.

Accessing Data — The General Approach

Say we have two child components (Component A & Component B) within a parent component and we would for some reason need to display some data from Component A in B and vice-versa. see rough sketch below:

component data sharing

The general and recommended approach would be to emit the data from A, add a listener/handler in the parent component, then pass the value into Component B via props. This would look something like this:

vue reactive system

In some cases, we might need to hack our way around and eliminate some steps from this flow to make the data passing trip slightly shorter. Say ComponentA wouldn’t need to emit its data value to the parent component, then we can remove the emit and listen steps and directly access the values in ComponentA from the Parent Component.

Yes, Sam, you can share your stuff with your sister without my permission.

Using $ref

Say we have two identical components — Component A & Component B.

Component A has two methods; setThought that sets the value of a thought data property to any value passed from the editable div, and another method — readMind that does nothing for now.

Component B is similar, with just a slight difference in content:

You may or may not have already figured out what we want to do here. We need Component A to be able to read Component B’s thoughts, without Component B emitting its thought.

For this, both components need to have something in common - their parent. To share data between two components using $ref , they need to be children of the same parent component. So in a parent component, we’ll import Component A and B into a parent component and assign ref attributes to both of them.

With this structure, we can easily access each component by reference from its parent like so:

this.$parent.$refs.componentA
OR
this.$parent.$refs.componentB

Now we can update the readMind method for Component A so that on button-click Component A would know exactly what Component B is thinking:

Notice we can access the thought data property in ComponentB by setting a ref attribute on it and accessing it from its parent.

We can make a similar update to the readMind method in Component B to do the same thing - find out what Component A is thinking.

What does this look like?

Mind reader?

Can we set component values too?

Sure, just like the 2010 movie — Inception, let’s force Component B’s thoughts to be exactly what Component A thinks about. We can set the value of the data properties in the same way:

Alternatively, you can call the setThought method of Component B from Component A:

What would this look like?

Inception?

Oh, refs are reactive?

No, they’re not. What you see is only a result of calling the setThought method every time there’s an input in Component A and in turn, setting the value of this.$parent.$refs.componentB.thought to the same value as the thought data property in ComponentA.

Refs are one of Vue’s quirky parts and can get troublesome if you do not properly understand their usage. The safest way to use them would be outside your lifecycle hooks and only within methods. Also, avoid direct usage within components' template or computed properties.

If you’d like to fiddle around with the source code, you’ll find it here:

Also, Here’s a detailed guide on how and where to safely access refs, and of course, the official documentation.

Cheers ☕️