DEV Community

Cover image for Dynamic Refs in Vue3 The Right Way
Waleed Asender
Waleed Asender

Posted on • Edited on

5 1

Dynamic Refs in Vue3 The Right Way

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>
Enter fullscreen mode Exit fullscreen mode

in Vue you will write:

<script>
  const commentCard = ref(null);
</script>

<div ref="comment-card">...</div>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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];
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! I hope this method help you in your development work.

Tiugo image

Modular, Fast, and Built for Developers

CKEditor 5 gives you full control over your editing experience. A modular architecture means you get high performance, fewer re-renders and a setup that scales with your needs.

Start now

Top comments (0)

Jetbrains image

Is Your CI/CD Server a Prime Target for Attack?

57% of organizations have suffered from a security incident related to DevOps toolchain exposures. It makes sense—CI/CD servers have access to source code, a highly valuable asset. Is yours secure? Check out nine practical tips to protect your CI/CD.

Learn more

👋 Kindness is contagious

Dive into this informative piece, backed by our vibrant DEV Community

Whether you’re a novice or a pro, your perspective enriches our collective insight.

A simple “thank you” can lift someone’s spirits—share your gratitude in the comments!

On DEV, the power of shared knowledge paves a smoother path and tightens our community ties. Found value here? A quick thanks to the author makes a big impact.

Okay