How many other developers out there have encountered the following scenario:
You have a Vue component that needs to use an HTML id
attribute to link elements together:
<template>
<div>
<label for="inputId">Label</label>
<input id="inputId" type="text">
</div>
</template>
But, as it turns out, you need to have multiple instances of that component on the page. To avoid breaking the page with id
collisions, you need a unique id for the input
element.
Unfortunately, Vue does not provide an instance id for components that you can key off of to do this.
What you'll often see other developers do is something along these lines (this is off the top of my head so forgive any silly errors):
<template>
<div>
<label :for="inputId">Label</label>
<input :id="inputId" type="text">
</div>
</template>
<script>
let id = 0
export default {
data() {
return {
inputId: null
}
},
created() {
id++
this.inputId = id
}
}
</script>
This will work for the most part until server-side rendering enters the picture. Due to separate thread processing, no matter what you do, id
will be out of sync on the server and on the client.
That is a real bummer, but there is a workaround.
I've written vue-uid for this very issue.
It is a tiny directive that generates a unique identifier that is automatically assigned to an element’s id
attribute.
Here is a usage example:
<script setup lang="ts">
import { ref } from 'vue'
const input = ref<null | HTMLElement>(null)
</script>
<template>
<div>
<label :for="input?.id">Input label</label>
<input v-uid ref="input" type="text">
</div>
</template>
The best part of this is that you don't need to write extra code or pull in additional dependencies to figure out how to generate a unique id in the first place, and second, it is SSR-friendly! Slap the v-uid
directive on an element and you are off to the races with a unique id you can count on.
If you'd like more understanding into how vue-uid works, be sure to read the Custom Directives documentation.
I hope you found this useful.
Thanks.
Top comments (1)
I was just about to go write something like this in frustration, after getting a gazillion id mismatch warnings after converting a project to use Vike, when I dug a little deeper into my Google search results and found this article (and vue-uid). Thanks!