In Vue.js, we can use ref to reference HTML elements and directly manipulate the DOM when necessary.
In general, Vue.js encourages a declarative approach to building the user interface. That is, we normally won’t have to touch DOM elements directly.
However, there are certain occasions where it will be necessary to access and manipulate DOM elements directly (third-party libraries, complex animations, certain complicated cases, etc.).
For this, Vue.js provides the ref utility, which allows us to get references to DOM elements or component instances.
Avoid directly manipulating the DOM when possible. Vue.js is designed to handle most DOM interactions declaratively.
What is ref in Vue.js
In Vue.js, we can use ref to create a reactive reference to an object or a DOM element (in addition to reactive values, as we saw when discussing reactivity).
To create a reference to a DOM element, we first import ref from Vue and then use it in the setup function.
On the other hand, in the template, we use the ref directive to bind a DOM element to the created reference.
<template>
<div ref="miElemento">This is a DOM element</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
// Create a reference
const miElemento = ref(null);
onMounted(() => {
// Access the DOM element after it mounts
console.log(miElemento.value); // <div>This is a DOM element</div>
});
</script>
In this example,
miElementois a reference to the<div>in the template.- After the component mounts (
onMounted), - we can access the DOM element through
miElemento.value.
Practical Examples
Change the content of an element
Suppose we want to change the content of a DOM element when the user clicks a button.
<template>
<div>
<p ref="texto">Click the button to change this text</p>
<button @click="cambiarTexto">Change text</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
const texto = ref(null);
function cambiarTexto() {
texto.value.textContent = 'The text has changed!';
}
</script>
In this example, the content of the <p> is changed directly when the user clicks the button.
Focus a text field
Suppose we want to automatically focus a text field when the component mounts.
<template>
<div>
<input ref="campoTexto" type="text" placeholder="Write something" />
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const campoTexto = ref(null);
onMounted(() => {
campoTexto.value.focus();
});
</script>
In this example, the text field is automatically focused when the component mounts to the DOM.
Integrate with a third-party library
Suppose we want to integrate a graphics library like Chart.js which requires direct access to a <canvas> element.
<template>
<div>
<canvas ref="miCanvas"></canvas>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import Chart from 'chart.js/auto';
const miCanvas = ref(null);
onMounted(() => {
const ctx = miCanvas.value.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June'],
datasets: [{
label: 'Sales',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'rgba(75, 192, 192, 0.2)',
borderColor: 'rgba(75, 192, 192, 1)',
borderWidth: 1
}]
},
options: {
scales: {
y: {
beginAtZero: true
}
}
}
});
});
</script>
In this example, we use ref to access a <canvas> element and create a chart with Chart.js.
