159

I have a component, how can I select one of its elements?

I'm trying to get an input that is within this component's template.

There could be multiple components so the querySelector must only parse the current instance of the component.

Vue.component('somecomponent', {
    template: '#somecomponent',
    props: [...],

   ...

    created: function() {
        somevariablehere.querySelector('input').focus();
    }
});

6 Answers 6

187

vuejs 2

v-el:el:uniquename has been replaced by ref="uniqueName". The element is then accessed through this.$refs.uniqueName.

Sign up to request clarification or add additional context in comments.

5 Comments

This helped me realize that the ref attribute works on any HTML element or Vue component. Good stuff.
It looks like this.$refs.uniqueName is an array, so you need to this.$refs.uniqueName[0] to get the referenced element.
only after the mounting component , which could be done in the parent's mounted method : medium.com/@brockreece/…
Why has this been labeled as vuejs 2? It also works in vue.js 3.
@PassivProgrammer because if you're using the Composition API / Vue 3 best practice you don't have access to this.$refs (this is void)
153

There's a few options depending on what you're trying to access:

  • You can access the child components of a Vue.js component with this.$children

  • You can label specific DOM elements inside your template using ref="uniqueName" and refer to these later via this.$refs.uniqueName
    (but remember that you won't be able to refer to these until the component/app has finished mounting and performed an initial render)

  • If you're unable to label your elements, you can query the DOM for child elements using a CSS selector via this.$el.querySelector('.myClass > .childElement')
    (as above, the component/app needs to have finished mounting)

You can also explore by doing a simple console.log(this) inside your component and it will show you all the properties of your Vue component instance.

1 Comment

Hint: this.$el is undefined until mounted. If you want to initialize a variable do it in mount()
60

The answers are not making it clear:

Use this.$refs.someName, but, in order to use it, you must add ref="someName" in the parent.

See demo below.

new Vue({
  el: '#app',
  mounted: function() {
    var childSpanClassAttr = this.$refs.someName.getAttribute('class');
    
    console.log('<span> was declared with "class" attr -->', childSpanClassAttr);
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  Parent.
  <span ref="someName" class="abc jkl xyz">Child Span</span>
</div>

$refs and v-for

Notice that when used in conjunction with v-for, the this.$refs.someName will be an array:

new Vue({
  el: '#app',
  data: {
    ages: [11, 22, 33]
  },
  mounted: function() {
    console.log("<span> one's text....:", this.$refs.mySpan[0].innerText);
    console.log("<span> two's text....:", this.$refs.mySpan[1].innerText);
    console.log("<span> three's text..:", this.$refs.mySpan[2].innerText);
  }
})
span { display: inline-block; border: 1px solid red; }
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  Parent.
  <div v-for="age in ages">
    <span ref="mySpan">Age is {{ age }}</span>
  </div>
</div>

1 Comment

Also important to note that reffed items are NOT reactive.
42

In Vue2 be aware that you can access this.$refs.uniqueName only after mounting the component.

1 Comment

Everything before mounted in Vue's lifecycle is not presented in your browser. Since it hasn't been mounted yet, there is no DOM available inspection.
8

Composition API

Template refs section tells how this has been unified:

  • within template, use ref="myEl"; :ref= with a v-for
  • within script, have a const myEl = ref(null) and expose it from setup

The reference carries the DOM element from mounting onwards.

4 Comments

so performing a query like document.querySelectorAll("nav > ul > li"); is out of the question?
No it's not. But there you start the query from document, the root. Since you are making a component, it should likely start from a node within the component.
ok so something like <header ref="headerEL">, where header is a parent of nav, then const headerEl = ref<HTMLElement>(), then you can do const links = headerEl.value.querySelectorAll('nav > ul > li')
(tips) add await nextTick(); before invoking myEl to ensure component is fully rendered.
7

Vue 2.x

For Official information:

https://v2.vuejs.org/v2/guide/migration.html#v-el-and-v-ref-replaced

A simple Example:

On any Element you have to add an attribute ref with a unique value

<input ref="foo" type="text" >

To target that elemet use this.$refs.foo

this.$refs.foo.focus(); // it will focus the input having ref="foo"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.