Acccessing DOM Elements with ref
The ref attribute in Vue provides a way to interact with DOM elements directly. When attached to a native HTML element, it functions similarly to a DOM ID but offers more flexibility:
<template>
<div ref="container">Content here</div>
</template>
<script>
export default {
mounted() {
const element = this.$refs.container
element.style.height = '300px'
element.style.background = 'blue'
console.log(element.offsetWidth)
}
}
</script>
This approach grants direct access to the underlying DOM node, enabling manipulation of styles, attributes, and dimensions.
Handling Dynamic Lists with ref
When ref is used alongside v-for, Vue creates an array of references:
<template>
<ul>
<li v-for="item in items" :key="item.id" ref="listItems">
{{ item.name }}
</li>
</ul>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, name: 'First' },
{ id: 2, name: 'Second' },
{ id: 3, name: 'Third' }
]
}
},
mounted() {
console.log(this.$refs.listItems) // Array of 3 li elements
}
}
</script>
Each iteration generates a corresponding entry in the $refs array, making batch operations on list items straightforward.
Referencing Component Instances
A more powerful use case involves binding ref to custom Vue components. This grants programmatic access to the component's internal state and methods:
<!-- CardComponent.vue -->
<template>
<div class="card">
<h2>{{ title }}</h2>
</div>
</template>
<script>
export default {
name: 'CardComponent',
data() {
return {
title: 'Default Title',
count: 0
}
},
methods: {
increment() {
this.count++
},
reset() {
this.count = 0
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<CardComponent ref="myCard" />
<button @click="updateCard">Update Card</button>
</template>
<script>
export default {
methods: {
updateCard() {
// Access the VueComponent instance directly
const cardInstance = this.$refs.myCard
// Modify component data
cardInstance.title = 'Updated Title'
// Invoke component methods
cardInstance.increment()
// Access the actual DOM element via $el
const domNode = cardInstance.$el
console.log(domNode.offsetHeight)
}
}
}
</script>
The $refs object returns a VueComponent instance rather than a raw DOM element. The intsance exposes $el for DOM access, along with direct references to reactive data and methods defined within the component.
This pattern proves essential when working with third-party UI libraries that expose component APIs—methods and properties can be invoked with out prop drilling or event emission overhead.