DEV Community

Cover image for How to use Vue Template Refs to Access HTML Elements
Johnny Simpson
Johnny Simpson

Posted on • Originally published at fjolt.com

How to use Vue Template Refs to Access HTML Elements

Vue gives us a lot of powerful features when it comes to manipulating the DOM. It simplifies the job of maintaining states, to create UIs which are easy to maintain, and fun to use. One thing Vue does really well, is removes the need for direct DOM manipulation. Sometimes, though, we still need to manipulate or reference DOM elements themselves. Fortunately, Vue has thought of this, and allows us to do this with the ref attribute.

Referencing DOM Elements in Vue

Although it's certainly possible to use .querySelector() on a Vue document, it's not best practice. If we want to reference a DOM element, we can use the ref attribute in Vue.

Let's look at a quick example. Below, we have our App.vue page, which has an input, and we want to reference that input directly in one of our methods:

<template>
    <button id="myButton">Some Button</button>
</template>

<script>
export default {
    mounted: function() {
    }
}
</script>

<style scoped>
button {
    background: black;
    color: white;
    border: none;
    border-radius: 4px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Vue can store references to DOM elements in a property called $ref. The first thing we have to do, is add a ref attribute to the element we want to reference in our Javascript. The value of the ref attribute will be the name of it within the $ref property.

For mine, I am calling it myButton:

<template>
    <button id="myButton" ref="myButton"></button>
</template>
Enter fullscreen mode Exit fullscreen mode

Next, in our Javascript, we can call upon that reference, as shown below:

export default {
    mounted: function() {
        console.log(this.$ref.myButton);
    }
Enter fullscreen mode Exit fullscreen mode

This will return the DOM element itself - so you can manipulate it like you'd manipulate any DOM element.

Accessing DOM Elements using Vue Template Refs

How to use Vue references to return a DOM element

Referencing Child Components
If our button was a component, we could also access it using the same ideas. For example suppose we have a child component, called TestComponent. We can add a ref directly to the child component, as shown below:

<template>
    <button id="myButton" ref="myButton">Some Button</button>
    <TestComponent ref="anotherButton">
</template>

<script>

import TestComponent from '../components/TestComponent.vue';

export default {
    components: {
        TestComponent
    },
    mounted: function() {
        // Console logs our "myButton"
        console.log(this.$refs.myButton);
        // Console logs "anotherButton"
        console.log(this.$refs.anotherButton);
    }
}
</script>

<style scoped>
button {
    background: black;
    color: white;
    border: none;
    border-radius: 4px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Above, we add ref to the component itself:

<TestComponent ref="anotherButton" />
Enter fullscreen mode Exit fullscreen mode

The difference here, is that it doesn't return the DOM element itself - it instead returns an object for the child component.

Referencing a child component with Vue Refs

Referencing a Child Component's DOM element
Since we get an object for a child component when using references, if we want to access the DOM element within a child component itself, we have to use $el - which will refer to the DOM element in the component itself.

// This is the child component reference
this.$refs.anotherButton
// This is the DOM element for the component
this.$refs.anotherButton.$el
Enter fullscreen mode Exit fullscreen mode

Referencing a Child Component's Method

Since a referencing a child component refers to the entire component, we can reference its methods using this reference. Let's say our child component has Javascript that looks like the code below.

TestComponent.vue:

<script>
export default {
    methods: { 
        someFunction: function() {
            console.log('Hello');
        }
    }
}
</script>
Enter fullscreen mode Exit fullscreen mode

In our main, App.vue file, we can reference this method through our reference. For example:

<template>
    <button id="myButton" ref="myButton">Some Button</button>
    <TestComponent ref="anotherButton">
</template>

<script>
import TestComponent from '../components/TestComponent.vue';
export default {
    components: {
        TestComponent
    },
    mounted: function() {
        this.$refs.anotherButton.someFunction();
    }
}
</script>

<style scoped>
button {
    background: black;
    color: white;
    border: none;
    border-radius: 4px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Above, since we have added a reference ref="anotherButton" to the child component, we can reference it in our Javascript through that reference. All methods are available through this reference:

this.$refs.anotherButton.someFunction();
Enter fullscreen mode Exit fullscreen mode

Using References with v-for

The same concepts apply to v-for. If you use a ref on a v-for element, each element produced by the v-for loop, will be returned as an array within that reference.

For example, let's say we have the following code:

<template>
    <ul>
        <li v-for="(item, index) in locations" :key="index" ref="myLocations">{{ item.name }}</li>
    </ul>
</template>

<script>
export default {
    data() {
        return {
            locations: [
                { name: 'London', date: '11/02/2022' },
                { name: 'Paris', date: '12/01/2022' },
                { name: 'Tokyo', date: '04/06/2021' }
            ]
        }
    },
    mounted: function() {
        let liElements = this.$refs.myLocations;
        console.log(liElements);
    }
}
</script>

<style scoped>
button {
    background: black;
    color: white;
    border: none;
    border-radius: 4px;
}
</style>
Enter fullscreen mode Exit fullscreen mode

Since we've added a ref called myLocations to our li element, we can now access it via this.$refs.myLocation. Since it is also a v-for, myLocation will be an array. To get the second li element, we would do the following:

this.$refs.myLocations[1];
Enter fullscreen mode Exit fullscreen mode

Conclusion

References in Vue are a powerful way to access the DOM elements that Vue produces. They are also the best way to do it when working within the Vue framework. I hope you've enjoyed this article. For more Vue content, you can find it here.

Top comments (0)