· Zen HuiFer · Learn · 7 min read
React's useId, now Vue3.5 finally has it!
Vue 3.5 introduces useId, a utility similar to React's for generating unique IDs. Essential for accessibility and server-side rendering consistency, useId helps avoid warnings and ensures unique element identifiers across the app.
React’s useId, now Vue3.5 finally has it!
preface
React was added in earlier versionsuseId
Used to generate a unique ID. In Vue 3.5 version, there is finally the long-awaiteduseId
. This article will help you clarifyuseId
What are the application scenarios and how is it implemented.
The role of useId
His function is also to generate a unique ID, which is called every time within the same Vue applicationuseId
The generated IDs are all different.
The usage method is also very simple, the code is as follows:
<script setup lang="ts">
import { useId } from 'vue'const id0 = useId();
console.log(id0); // v-0const id1 = useId();
console.log(id1); // v-1const id2 = useId();
console.log(id2); // v-2
</script>
Some friends may have problems seeing this. The examples above are all called within the same componentuseId
. If I call them separately in different componentsuseId
Are the IDs generated by these components still unique?
For example, in the following example, the parent component code is as follows:
<template>
<div>
<UseIdChild1 />
<UseIdChild2 />
</div>
</template>
SubcomponentsUseIdChild1
The code is as follows:
<script setup lang="ts">
import { useId } from "vue";const id0 = useId();
const id1 = useId();console.log(id0);
console.log(id1);
</script>
SubcomponentsUseIdChild2
The code is as follows:
<script setup lang="ts">
import { useId } from "vue";const id0 = useId();
const id1 = useId();console.log(id0);
console.log(id1);
</script>
From the above code, you can see that the code inside the two sub components is actually the same. Can you guess what the sub components areUseIdChild1
Printed in the middleid0
、id1
And sub componentsUseIdChild2
Printed in the middleid0
、id1
Is it the same?
The answer is: dissimilarity 。
UseIdChild1
Printed in the middleid0
The value isv-0
,id1
The value isv-1
。
UseIdChild2
Printed in the middleid0
The value isv-2
,id1
The value isv-3
。
Based on the above two examples, I think you should guessuseId
The rule of generating unique IDs for functions: “Stringv-
add Self increasing numbers
”。
The prefix in itv
Can be done throughapp.config.idPrefix
Customize.
Sometimes when we need to render a list of data, we need each item in the list to have a unique ID. In this case, we can useuseId
Generate a unique ID for each item.
This is the simplest usage scenario. Next, let’s take a look at server-side rendering (SSR)useId
The usage scenario.
Using useId in server-side rendering (SSR)
Firstly, we need to identify the pain points during server-side rendering?
Let’s take a look at an example of server-side rendering. The code is as follows:
<template>
<div>
<label :htmlFor="id">Do you like Vue3.5?</label>
<input type="checkbox" name="vue3.5" :id="id" />
</div>
</template><script setup lang="ts">
const id = Math.random();
</script>
If the above code runs on the client-side rendering, there will be no problem, but if it runs on the server-side rendering, there will be a warning. As shown in the following figure:
The warning above means that the value of the ID generated on the server is0.4050816845323888
. But the value of the ID generated on the client side is0.4746900241123273
The ID values generated these two times are different, which is why the warning appears.
Some friends may wonder why the ID is generated again on the client after being generated on the server?
To answer the above question, let’s first understand the process of server-side rendering (SSR):
Firstly, an interface request will be initiated on the server (Node.js environment) to retrieve the data required for page rendering from the backend.
Generate an HTML string for the page based on the received data, and at this point, an ID will be generated on the server. This step is called
dehydrate
(Dehydration).Send the HTML string generated by the server to the client (browser).
The browser can use the HTML string generated by the server as the first screen content and directly render it onto the page. But at this point, events such as click have not yet been bound to the DOM, so they need to be rendered again on the client side. Will generate the ID again on the client side, this step is called
hydrate
(Water injection).
Since we are usingMath.random()
Generate the ID and execute it on both the server and client every timeMath.random()
The generated ID value is naturally different, which is why the warning above appears.
Got ituseId
After that, resolving the warning above is very simple, just put it in placeMath.random()
Change touseId()
That’s enough. The code is as follows:
<template>
<div>
<label :htmlFor="id">Do you like Vue3.5?</label>
<input type="checkbox" name="vue3.5" :id="id" />
</div>
</template><script setup lang="ts">
const id = useId();
</script>
becauseuseId
Generated during server-side renderingv-0
Still rendering on the client sidev-0
。
Some friends may have questions, which were not mentioned earlieruseId
Each execution will give the following numbers+1
. So, after executing once on the server, should the generated ID be different when executing again on the client??
useId
The generated ‘auto increment part’ is maintained on the Vue instanceids
In terms of properties, a Vue instance will be generated on the Node.js side during server-side rendering. But when the client renders, a new Vue instance will be generated in the browser, and at this timeids
The attributes will also be reset, so they will be executed on both the server and client sidesuseId
The generated values are the same.
How is useId implemented
Let’s take a lookuseId
The source code is very simple!! The simplified code is as follows:
function useId(): string {
const i = getCurrentInstance()
if (i) {
return (i.appContext.config.idPrefix || 'v') + '-' + i.ids[0] + i.ids[1]++
}
return ''
}
thisgetCurrentInstance
I think many students are familiar with the function, which returns the current Vue instance.
touseId
Make a breakpoint to take a look at the current Vue instancei
, as shown in the following figure:
From the above figure, it can be seen that on the Vue instanceids
A property is an array, where the first item is an empty string, the second item is the number 0, and the third item is also the number 0
Let’s take another lookuseId
How to return a unique ID, as follows:
return (i.appContext.config.idPrefix || 'v') + '-' + i.ids[0] + i.ids[1]++
The generated unique ID consists of three parts:
The first part is the prefix, from
app.config.idPrefix
Taken from the middle. If there is no configuration, then it is just a stringv
。The second part is to write a dead string
-
。The third part is
i.ids[0] + i.ids[1]++
Among themids[0]
The value is an empty string.i.ids[1]++
Here, the value is taken first, and then executed++
So the value of the third part is a number0
. Call againuseId
When, due to the previous execution++
That’s it. The current numerical value is1
And execute it again++
。
Some of the buddies here have questions again. It looks likeids
The attribute exists on the Vue instance. Each Vue component has a Vue instance, so each component has its own maintenanceids
Attributes. In the example you mentioned earlierUseIdChild1
Subcomponents andUseIdChild2
Generated by each sub componentid0
The value should be the samev-0
Well, why is onev-0
The other one isv-2
What about it?
The answer is actually quite simple, on all Vue instancesids
The attributes are all the same array, pointing to the one above the top-level component instanceids
Attributes. The source code for creating a Vue instance is shown in the following figure:
From the above figure, it can be seen that when there is no parent component, which is the top-level Vue component instance, it will beids
Set attribute as array['', 0, 0]
。
When generating Vue instances of child components, due to the presence ofids
Attribute, so we used the one above the parent component. The pointers all point to the top-level Vue instanceids
That’s why all Vue component instances have attributesids
All attributes point to the same array.
That’s whyUseIdChild1
Subcomponents andUseIdChild2
Generated by each sub componentid0
The value of one isv-0
The other one isv-2
。
summary
New additions to Vue 3.5useId
We can generate unique IDs within Vue applications, and we can use themuseId
Generate a unique ID for each item in the list data.
And in the server-side rendering (SSR) scene, both the server-side and client-side executeuseId
The generated ID is the same. We can use this feature touseId
Resolve warnings caused by inconsistent IDs generated by the server-side and client-side in SSR applications.
Finally, we talked aboutuseId
The implementation is also very simple, and the generated ID is divided into three parts:
The first part is the prefix:
app.config.idPrefix
If there is no configuration, then it is just a stringv
。Part 2 String:
-
。The value of the third part is a self increasing number that exists on the Vue instance
ids
Attributes, on all Vue instancesids
All attributes point to the same array. That’s why it’s saiduseId
Can be inVue in app
Generate a unique ID instead ofWithin Vue components
Generate a unique ID.