Vue Template Refs

Direct access to DOM elements and components

🎯 What are Template Refs?

Template refs provide direct access to DOM elements or child component instances in your template. Use them when you need to manipulate elements directly, focus inputs, or access component methods imperatively.


<!-- Basic Template Ref -->
<template>
  <input ref="inputRef" type="text" />
  <button @click="focusInput">Focus Input</button>
</template>

<script setup>
import { ref } from 'vue'

const inputRef = ref(null)

function focusInput() {
  inputRef.value.focus()
}
</script>
                                    

Key Template Ref Concepts

🔗

Element Refs

Access DOM elements directly

<div ref="divRef"></div>

const divRef = ref(null)
🧩

Component Refs

Access child component instances

<ChildComp ref="childRef" />

const childRef = ref(null)
📋

v-for Refs

Array of refs in loops

<div v-for="item in list" 
     ref="itemRefs">
</div>
âš¡

Function Refs

Dynamic ref assignment

<div :ref="el => setRef(el)">
</div>

🔹 Basic Element Ref

Access and manipulate DOM elements directly:

<template>
  <div>
    <input ref="nameInput" type="text" placeholder="Enter name" />
    <button @click="focusInput">Focus</button>
    <button @click="clearInput">Clear</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const nameInput = ref(null)

function focusInput() {
  nameInput.value.focus()
}

function clearInput() {
  nameInput.value.value = ''
}
</script>

🔹 Component Ref

Access child component methods and properties:

<!-- Parent Component -->
<template>
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">Call Child Method</button>
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const childRef = ref(null)

function callChildMethod() {
  childRef.value.childMethod()
}
</script>

<!-- Child Component -->
<script setup>
import { defineExpose } from 'vue'

function childMethod() {
  console.log('Child method called!')
}

// Expose method to parent
defineExpose({
  childMethod
})
</script>

🔹 Refs in v-for Loops

Collect multiple element references in an array:

<template>
  <div>
    <div 
      v-for="(item, index) in items" 
      :key="item.id"
      ref="itemRefs"
      class="item"
    >
      {{ item.name }}
    </div>
    <button @click="highlightFirst">Highlight First</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, name: 'Item 1' },
  { id: 2, name: 'Item 2' },
  { id: 3, name: 'Item 3' }
])

const itemRefs = ref([])

function highlightFirst() {
  if (itemRefs.value[0]) {
    itemRefs.value[0].style.background = 'yellow'
  }
}
</script>

🔹 Function Refs

Use a function for dynamic ref assignment:

<template>
  <div>
    <input 
      v-for="n in 3" 
      :key="n"
      :ref="el => setInputRef(el, n)"
      type="text"
    />
    <button @click="focusSecond">Focus Second Input</button>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const inputRefs = ref({})

function setInputRef(el, index) {
  if (el) {
    inputRefs.value[index] = el
  }
}

function focusSecond() {
  inputRefs.value[2]?.focus()
}
</script>

🔹 Practical Example - Video Player

Control a video element using template refs:

<template>
  <div>
    <video ref="videoRef" width="400">
      <source src="video.mp4" type="video/mp4">
    </video>
    
    <div class="controls">
      <button @click="play">Play</button>
      <button @click="pause">Pause</button>
      <button @click="restart">Restart</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const videoRef = ref(null)

function play() {
  videoRef.value.play()
}

function pause() {
  videoRef.value.pause()
}

function restart() {
  videoRef.value.currentTime = 0
  videoRef.value.play()
}
</script>

🧠 Test Your Knowledge

What is the purpose of template refs in Vue?