Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can vue provide useId hook #556

Closed
RhysXia opened this issue Dec 16, 2021 · 6 comments
Closed

Can vue provide useId hook #556

RhysXia opened this issue Dec 16, 2021 · 6 comments

Comments

@RhysXia
Copy link

RhysXia commented Dec 16, 2021

What problem does this feature solve?

In the SSR environment, sometimes it is necessary to create a stable id that is the same on the server and the client.

For example, a server request wants to put the requested data in html (for example window.SSR_DATA={//data}), and then the client obtains and uses the data through a specific key from SSR_DATA.

We can encapsulate this method into a hook, for example called useServerData.

useServerData may be used multiple times by the same component, or it may be used by multiple components. Therefore, this key is required to be globally unique and the same in the same place on the server and client.

We can also guarantee uniqueness by passing the key to useServerData. But this is very inelegant and there is no way to guarantee that it will be unique. For example, useServerData is used in multiple components, so we need to go to each component code to confirm whether there is any duplication.In fact, this key does not need to be concerned about the component at all.

So can vue provide a way to generate id staying stable and unique between server and client?

A similar hook is provided in react18, you can refer to.

What does the proposed API look like?

const id1 = useId();
const id2 = useId(); // id1 !== id2
@danielroe
Copy link
Member

I've released a tiny directive that may help: vue-bind-once. Sample usage:

<div v-bind-once="{ id: Math.random() }" />

This will work on both server and on client re-hydration.

@RhysXia
Copy link
Author

RhysXia commented Feb 23, 2022

@danielroe Is this method only available for binding on elements? I want this id to be available everywhere,like hooks.

@jshimkoski
Copy link

jshimkoski commented Feb 23, 2022

Another option (not as flexible as vue-bind-once but inspired by it) is: vue-uid

It generates an SSR-friendly unique identifier that is automatically assigned to the id on the element.

Sample usage:

<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>

Both vue-bind-once and vue-uid are only available when bound to elements as they are directives. Both use getSSRProps() as documented here: https://vuejs.org/guide/scaling-up/ssr.html#custom-directives

@LeBenLeBen
Copy link

In case you’re looking for a composable, I came up with that solution: https://github.com/liip/chusho/blob/main/packages/chusho/lib/composables/useCachedUid.ts#L20-L41

@simonmaass
Copy link

is there any idea for vue2?

@wobsoriano
Copy link

@LeBenLeBen I see different values for client and server when I use that composable in Nuxt

@sodatea sodatea transferred this issue from vuejs/core Sep 1, 2023
@vuejs vuejs locked and limited conversation to collaborators Sep 1, 2023
@sodatea sodatea converted this issue into discussion #557 Sep 1, 2023

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
Status: No status
Development

No branches or pull requests

7 participants