Vue3 Template Ref

Posted on  by admin

Template refs on components

In this Vue tutorial we learn how to access DOM nodes directly from within Vue and use lifecycle methods to manipulate it.

We cover how to define and access refs on both elements and entire component instances.

If you want to follow along with the examples, you will need an app generated by the Vue CLIas well as the following extra component.

The project should look similar to the following.

The root App component imports and uses theTemplateRefcomponent.

TheTemplateRefcomponent can just show an identifying message in a paragraph to start with.

Template Refs make it possible to access DOM nodes directly from within Vue.

As an example, let’s say we have a login form and want to focus the email/username field when the page loads.

We can access the input with a template ref and focus it in a lifecycle method.

We define a template ref with therefattribute, which will register a new reference to an element or component.

It’s value is an identifier that we use later on to access the reference.

As an example, let’s create a text field in ourTemplateRefcomponent with a ref calledtextInputRef.

We’ll also add a focus CSS style to help the demonstration. To access a template ref, we use the$refsinstance variable with the identifier we assigned to it.


As an example, let’s access our textInputRef and chain thefocusmethod to it in the mounted lifecyclehook.

The method will set the text input to a focussed state when the component is mounted.

If we save the file and reload the page in the browser, the text input will show a blue outline, indicating that it has focus.

We mentioned earlier thatrefcan be used on a component as well.

Let’s see an example by creating a new component calledGreetingMessage.

It will have a single data property that we output in the template.

We’ll nest the new component inTemplateRefand add arefto it.

Then we’ll access the msg data property with the identifier and log it to the console.

If we run the example in the browser, the console will show the “Hello, World!” message from theGreetingMessagecomponent.

Vue Template Refs give our Javascript code a reference to easily access the template.

For example, if we needed quick access to a component or HTML element, template refs is the perfect solution.

In Vue 3, the Composition API gives us another way to use template refs.

It joins the concept of reactive refs and template refs giving us just one syntax in our Javascript for both situations.

In this tutorial, we’ll be learning all about template refs: how to use them in both the Options API and Composition API, some advanced refs techniques, as well as look at good times to use this feature.

Let’s jump right in.

For our example, we’re going with the standard use case of focusing an input when a user loads a page.

This is useful because it can avoid people having to click in a text input and saves extra time.

An example of this functionality is on Google’s home page.

But first, we need to create a text input and give it a ref.

Regardless if we’re using the Options API or Composition API, we declare refs in our template the same way.

On any element or component, we have to specify an attribute called ref and pass it a unique reference ID as a String.

That’s it for our template, now let’s see how to access it in our script.

For the Options API, we have access to refs using the this object.

Vue stores all template refs under the property this.$refs.

An important note here is that in order for our refs to be accessible, our component must already have rendered on the screen.

This means that any point in the Vue lifecycle before mounting (like in created), we won’t have access to template refs.

The first place we have access to template refs is inside mounted.

So let’s listen for that lifecycle hook, access our ref, and focus it.

Now, if we reload our browser, we’ll see that our browser is automatically focused and we can type without having to click it first.

Now time for the Composition API.

Just to reiterate, the Composition API merges the concept of reactive data via ref with the concept of template refs.

So all we have to do is create a ref with the same name as the ref attribute in our template.The ref has a default value of null and will actually be the value of the input once our component is mounted.

Then, to focus it, we again have to use the onMounted lifecycle hook so our component has a chance to render.

But since we’re working in the Composition API, we have to import this hook and use it inside the setup function.

Inside, we can easily call input.value.focus().

And if we look back at our app, we have the same functionality as we did the Options API.

Next up, let’s take a look at some interesting interactions between v-for and other interactions in Vue.

I’m going to expanding on examples from the Vue docs themselves.

This interaction is useful whenever we’re rendering a list with a v-for loop and we want to create a ref for each element.

Inside of our script, we can create a ref that contains an empty array.

And then, in the element we are creating, we can programmatically add elements to our array based on the index in the v-for loop.

This is the simplest way to get a list of elements inside a template ref.

We can also use Vue’s watchEffect method to automatically detect changes to our template ref.

This is an interesting way to avoid using lifecycle hooks because we can simply watch for when our template ref is no longer null (meaning our component has mounted and rendered).

To do this, we can use the flush: post option on a watchEffect.

This will make our watchEffect wait until our DOM is rendered before running.

While the example we looked at – focusing an input – is one of the most common use cases for Vue template Refs, there are endless possibilities where this feature can be useful for your project.

Here are some examples:.

Animating an element using Javascript.

Easily changing the inner text or HTML of an element.

Passing a reference to an element as a prop.

I’d love to hear what other ideas you have, let me know down in the comments!

And as always, if you have any questions, I’m always around responding to the replies.

This section uses single-file component syntax for code examples.

This guide assumes that you have already read the Composition API Introduction and Reactivity Fundamentals.

Read that first if you are new to Composition API.

When using the Composition API, the concept of reactive refs and template refs are unified.

In order to obtain a reference to an in-template element or component instance, we can declare a ref as usual and return it from setup():.

Here we are exposing root on the render context and binding it to the div as its ref via ref="root".

In the Virtual DOM patching algorithm, if a VNode's ref key corresponds to a ref on the render context, the VNode's corresponding element or component instance will be assigned to the value of that ref.

This is performed during the Virtual DOM mount / patch process, so template refs will only get assigned values after the initial render.

Refs used as templates refs behave just like any other refs: they are reactive and can be passed into (or returned from) composition functions.

Composition API template refs do not have special handling when used inside v-for.

Instead, use function refs to perform custom handling:.

Watching a template ref for changes can be an alternative to the use of lifecycle hooks that was demonstrated in the previous examples.

But a key difference to lifecycle hooks is that watch() and watchEffect() effects are run before the DOM is mounted or updated so the template ref hasn't been updated when the watcher runs the effect:.

Therefore, watchers that use template refs should be defined with the flush: 'post' option.

This will run the effect after the DOM has been updated and ensure that the template ref stays in sync with the DOM and references the correct element.

See also: Computed and Watchers.

You block advertising 😢Would you like to buy me a ☕️ instead?

If you’re used to working with Vue 2 $refs and switch to the Vue 3 Composition API, you might wonder how to use $refs inside the new setup() method.

In this article, we find out how to use the new ref() function as a replacement for static and dynamic HTML element references.

When using the Vue 3 Composition API via the setup() method, we don’t have access to this.$refs, rather, we can use the new ref() function for the same result.

You might wonder how this can work with dynamic references.

Luckily after a short chat with Carlos Rodrigues, I knew the answer (the information is also in the official API documentation, but I somehow missed it).

Above you can see the example für dynamic Vue Composition API $refs from the official documentation.

Register for the Newsletter of my upcoming book: Advanced Vue.js Application Architecture.

Although at first, I didn’t like the new $refs API very much, it gets the job done.

I think it’s only a matter of time until we get used to the new way of doing things with the Composition API.

Modified5 months ago. This is a normal way to define a ref in vue3, but in JavaScript way.And if I'm using TypeScript, I will need to define a type for value element, right?

How do I do to ensure the correct type for value element?

3030 bronze badges.

48311 gold badge55 silver badges1313 bronze badges.

55 silver badges1313 bronze badges.

Well, that would depend on whether or not you need it typed and to provide member information (public properties, methods, etc).

If you do, then yes you need to define a type for it; otherwise, you don't have to, and can simply access the unwrapped reference with .value which leaves it as type any (I bet you figured out this one).

But if you have to, you need to tell the compiler what it is or what it's going to be assigned on.

To do that, you'll want to use the third overload of ref (with no argument) and explicitly set the generic type to the desired type—in your case, you want HTMLDivElement (or simply HTMLElement if you don't care about the specific members it has to offer).

In JavaScript, you don't have type checking, so passing null on the ref function is as good as not passing anything (which is especially okay for template refs)*; it could even come across as being misleading in a sense that the unwrapped value actually resolves to something else butnull.

* When using the Composition API, the concept of "reactive refs" and "template refs" are unified.

And the reason we're accessing this particular type of ref on the mounted hook is because the DOM element will be assigned to it after initial render.

22 gold badges2424 silver badges4242 bronze badges.

4242 bronze badges.

The line isn't correct:.

The el is not an HTMLDivElement.

Instead, it's a proxy to the element.

The $el of that proxy is the actual HTMLDivElement.

Though I'm not sure if I get it right.

In a component, I managed to type it as follow:.

22 gold badges1212 silver badges1010 bronze badges.

1010 bronze badges.

return{

msg1,

str2,

str,

s,

str1Change,

obj,

objChange

}

}

}

Declaring our Template Refs

Usage with JSX