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
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:
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:
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.
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?
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?
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
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: