[SOLVED] This.$refs.key returns undefined when it really is

I have a problem exactly the same as defined here although this one is archived.

I am using Vue 2.0 with Webpack. When I say console.log(this.$refs) (inside created() method inside a low level component) it returns:

▼ Object {}
    ▶ b254c249a585740ef79c26e71a8739ac: a.envelope
    ▶ __proto__: Object

, but when I say console.log(this.$refs.b254c249a585740ef79c26e71a8739ac) I get undefined.

1 Like

If you look at the lifecycle digramm you can see that when the created() hook is called, the component’s template/render function has not been compiled.

That’s why at this moment, this.$refs.someName is undefined - the referenced component simply hasn’t been created yet.

When you log the $refs object, it will also not contain this component at this very moment - but since the program will continue to run, the component will be added to the object immediately afterwards, when the content is rendered - that’s why you can see it in the console.

Try adding a breakpoint after the console.log() and you will be able to see that $refs has not been populated with any referenced components yet.


Thank you for this extensive explanation. Could you explain what is a use-case or how is the $refs object useful then? :slight_smile:

@DCzajkowski $refs contains registered children of the current component, allowing you to, for instance, access their methods/properties directly.

<child-component ref="childComponentA"></child-component>
<a @click.prevent="triggerChildMethod">Trigger A's method</a>
methods: {
  triggerChildMethod() {

Personally, I find myself using ref on non-components sometimes, for the sake of convenience :slight_smile:

<div tabindex="-1" ref="focusableDiv"></div>
<a @click.prevent="setFocus">Focus</a>
methods: {
  setFocus() {
    // I can access the DOM object directly here without any query.
1 Like

Ok. That makes sense. It would be cool though if you could interact with the DOM on (or just after) initial render using the ref, but it makes sense, I guess.

Thanks guys :slight_smile:

Well, you can. in mounted(), $refs has those components ready for you.

Look at the lifecycle diagramm again :wink:


The lifecycle diagram helped a lot. Thanks!

Hi. I am trying to access $refs inside mounted() and I am getting a weird scenario. When I console.log $refs, I can see the $refs object and the ref I am looking for.
However when I console.log $refs.myRef, undefined is printed.
Am I doing something wrong?

 mounted() {
    console.log('*mounted', this.$refs); // I can see myRef inside the $refs object in the console
    console.log('*mounted', this.$refs.myRef); // prints undefined
    console.log(this.$refs.myRef[0]); // Error: Cannot read property '0' of undefined

Just read my explanations in this thread, especially this comment: [SOLVED] This.$refs.key returns undefined when it really is

I explain just what you experience.

But @matan188 is using it inside mounted(), not created(), so it should be available, no?

That depends, I don’t know anything about his component. maybe he has a v-if on the component that only resolves to true after some data has been loaded asynchronously.

That would result in the same effect. Other things are possible as well.


Thanks for the quick reply!
That’s exactly what’s happening! I am loading some data asynchronously in the beforeMount() hook and didn’t realize it could affect the mount() logic. However, I do find it quite odd that I can see the myRef object when I print $refs to the console, I guess that has to do with the thread you referred me to. Anyway thanks a lot!
Now I just have to figure out how to reach that ref… I want to add an event listener to an element that is contained inside that ref component. The ref is on a Bootstrap element, so I cannot access its child directly.
Is there a good way for doing this?

1 Like

I figured it out!
It is possible to add native events to Bootstrap inputs by using the native modifier so no need to use addEventListener.
i.e: <b-form-input @focus.native="myFunction" />

According to what you said. We cannot get $refs in created is because render function is not yet compiled. And refer to the lift cycle diagram. $refs should be ready in beforeMount state. However. I can only get $refs content in mounted state. :frowning:

Oh my God! You are right, boy!

when v-if in component child modify to show, the lifecycle call again…

nice info.

same problem

If someone needs help, wrapping the this.$refs in this.$nextTick` will wait for the code render.

this.$nextTick(() => {

I’ve read all but I have a similar problem:

<div v-if="step==1">
    <button @click="setName">Set Name</button>

<div v-if="step==2">
    <input type="text" id="userName" ref="userName" v-model="item.name"/>

In the methods:

setName() {
    this.step = 2;
    Vue.nextTick(() => {

When I click the button I get:
userName: input#userName (for the first console log)
undefined (for the second console log)