Dynamic Refs in Vue3 The Right Way
Waleed Asender
Posted on October 1, 2023
Understanding Refs
Refs in Vue are a way to access and manipulate DOM elements or component instances. You may consider it as the Vue replacement for getElementById
.
Instead of writing:
<script>
const commentCard = document.getElementById('comment-card');
</script>
<div id="comment-card">...</div>
in Vue you will write:
<script>
const commentCard = ref(null);
</script>
<div ref="comment-card">...</div>
then you can manipulate the element commentCard
as you wish.
The Pitfall of Static Refs
Unfortunately, In many cases, static refs are bound to a specific element or component during initialization. This can become problematic when dealing with dynamic UIs where elements are created or removed based on dynamic fetched data.
Scenario
Let's say we have a blog with comment list, and we want to reference each comment DOM, but this comment list is dynamic and we don't know how many comments will be there:
<template v-for="comment in comments" :key="comment.id">
<CommentCard
:commentId="comment.id"
:ref="`commentCard${comment.id}`"
/>
</template>
If we need for any reason to manipulate these elements or components it will be difficult to reference them using static Refs commentCard1
, commentCard2
, commentCard3
..., we will need to bound the whole block with a parent Ref then call a function to refresh the list of child elements every time we want to interact with it, this will cause performance issues and may fail in some cases.
Solution
Instead of defining static Refs, we need to generate dynamic Refs for the element in the loop in as callback, and assign them to a Vue object variable using 'Function Refs':
<script>
import { ref } from "vue";
const commentCardRef = ref({});
</script>
<template v-for="comment in comments" :key="comment.id">
<CommentCard
:commentId="comment.id"
:ref="(el) => (commentCardRef[comment.id] = el)"
/>
</template>
This means we'll collect the Ref of each created DOM element in the loop and store them in this object. This gives us easy access to all the DOMs, letting us change them using their assigned Ids:
commentCardRef.value[comment.id];
Thanks for reading! I hope this method help you in your development work.
Posted on October 1, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.