Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

New RouterLink prop to provide useLink implementation #2568

8ctavio started this conversation in Ideas
Discussion options

Summary

Addition of new RouterLink prop to receive an instance of useLink's returned value instead of internally creating one with the currently required to prop, that is, either to or the new prop should be provided. This enables convenient consumption of useLink's reactive variables (like isActive) in components relying on RouterLink while preventing the creation of an additional useLink's instance.

Basic example

<script setup>
const link = useLink({/* ... */})
// useLink's instance available during setup...
</script>
<template>
 <!-- Provide link implementation -->
 <RouterLink :link>
 </RouterLink>
</template>

Motivation

RouterLink exposes through slot props internal state that is useful to add to or extend its functionality. However, when using composition API, it may be more convenient to access that internal state in the setup function. This might be specially the case for components extending/wrapping RouterLink.

Although there are some ways to extract RouterLink's internal useLink instance, providing it through a prop is probably the most simple, API-friendly, and convenient way.

Detailed design

For the purpose of this discussion, let the new RouterLink prop's name be link.

The implementation would require:

  • Making RouterLink.to prop not required (when defining component props).
  • Adding the new link prop with UseLinkReturn type.
  • In RouterLink's setup, instead of directly calling useLink, check for a provided link prop:
    - const link = reactive(useLink(props))
    + const link = reactive(props.link ?? useLink(props))

In addition, the RouterLinkProps type could be defined as an union, so that either the to or link prop is provided. The RouterLinkOptions and RouterLinkProps could be updated in the following way:

// Properties required by `useLink`
interface RouterLinkOptions {
 to: RouteLocationRaw
 replace?: boolean
 viewTransition?: boolean
}
// RouterLink-exclusive props
interface RouterLinkBaseProps { /* ... */ }
type RouterLinkProps = RouterLinkBaseProps & (RouterLinkOptions | { link: UseLinkReturn })
  • viewTransition is moved to RouterLinkOptions.
  • RouterLinkProps renamed to RouterLinkBaseProps.
  • Added RouterLinkProps union type.

Drawbacks

  • Components extending RouterLink might need to refactor types to support new link prop.

Alternatives

Working alternatives

Extract RouterLink slot props.

A functional component could be used to extract slot props, but it's comparatively more cumbersome, and data is not really available during setup, but until the component is being mounted.

Create a Link component.

The useLink composable could be used for convenience in the setup function, but in order not to create a duplicate useLink instance, a new Link component could be implemented. However, for scenarios where nothing additional to RouterLink is required, a new Link component would rewrite a big part, if not all, of RouterLink's implementation.

Use useLink for setup and RouterLink for template independently.

This is the closest API-wise to the proposed API, but as mentioned, two identical useLink instances would be created.

This approach is used to implement NuxtLink. In NuxtLink's implementation, useNuxtLink is called in the setup function (which internally calls vue-router's useLink), and then RouterLink is rendered.

Implementation alternatives

Expose internal RouterLink useLink instance (with setup's ctx.expose). This is similar to extracting the RouterLink slot props; the API would be somewhat improved with useTemplateRef, but I think the drawbacks are the same.

You must be logged in to vote

Replies: 0 comments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet
1 participant

AltStyle によって変換されたページ (->オリジナル) /