-
-
Notifications
You must be signed in to change notification settings - Fork 5k
Button as router-link (please see details) #3003
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
Comments
See #2021 |
Hi @posva, the issue isn't about having the capability, its a feature request for a more straightforward API. Thanks for the mention of the slots API though, thats probably the best current method so I'll add it as a 6th solution to the original post. I read about the slots API, but the documentation describes it as "advanced", "low-level customization", that was "primarily for library authors". I figured something like that wouldn't be required for something as simple as a making a button click go to a new page. If an advanced API is required, then I'd suggest it needs to be adjusted. Others likely will not know that this is the recommended solution since the stack overflow post doesn't mention it, and the documentation doesn't describe this as one of the use-cases for the slots API. I'll add this answer to the stack overflow post. |
That's expected, the cmd/ctrl click is native, it's not emulated by Vue Router. Buttons do not have that behavior, and I don't recommend you to change it. If you want the button to behave like a link, it should be a link for usability reasons like accessibility. If you still want to use a button, you will have to emulate link behaviors, but that has nothing to deal with Vue Router |
There are browsers out there that treat anchor-tags and button-tags very differently. Your opinion that everyone should just quit using buttons or list-elements for hyperlinks is very naive. Please give us back the router-link "tag" attribute, that was a perfectly simple solution in vue2. The "v-slot" solution is absurdly complicated. |
What is the initial issue?
Using a button from a library, for example
And making it behave as a router-link.
Solution 1: Why not use the
tag
property?example:
<router-link tag='ui-button' />
This is the first solution many seem to reach, however the
color="primary"
property needs to be passed to the ui-button (otherwise it is invisible in my use-case). So, the question becomes: how do I pass props to the router-link button? There does not currently seem to be a direct way to do this.Solution 2: Why not just Wrap the Button in a router-link?
example:
This has a few drawbacks. When using a button from a library, the button can have margins or may change css-properties such as
align-self: flex-start
. When the button is wrapped, this can obviously cause problems and makes the library not behave as intended: clicking the margin of a button should not activate the button. In addition to that, the default router-link tag is the anchor tag, which means the user must go learn about thetag
property and change it, lest they want all of their buttons to have underlined text. This is not an ideal programmer experience.Solution 3: Why not use $router ?
example:
<ui-button @click="()=>$router.push('about')" />
This does not behave the same as an href or router-link. For example, router-links can be opened in a new tab by pressing CMD/CTRL CLICK, however that behavior doesn't happen on an
@click
like the one above. This is generally a tell-tale sign of a poorly coded SPA site and is not an ideal user experience. However, making it an ideal user experience requires a non-ideal developer experience.Solution 4: Why not create a custom component wrapper?
example:
<router-link tag='custom-button'>
This would work, except for when the button needs the page name or other parent-dependent data to be passed as an attribute/property. Even if this did work, the bulkiness of this solution is problematic. Making a component redirect is incredibly basic functionality. Requiring an the creation of a wrapper component, registering it, and then attaching it to the router-link is a disproportional amount of work for such a straightforward goal.
Solution 5: Why not use href?
example:
<ui-button href='page-route' />
This circumvents the process, which makes page-transition animations and other aspects fail.
Solution 6: Why not use the slots API?
example:
This is now my current solution, and is likely the best solution. However, the documentation describes the slots API as "advanced", "low-level customization", that is "primarily for library authors". Requiring devs to dive all the way into the most advanced features just for a button click is not a good experience. The slots API is very extensive, so if this was advertised as the default method of creating router-links then this likely wouldn't be as much of an issue.
What is the final issue?
This is a common task, with 5 separate unintuitive ways to poorly accomplish it, an one relatively hidden advanced but good solution. Ideally there would be one obvious standardized ideal way. As a developer, I feel like I am required to become Vue-Router expert just to make a button redirect to a new page. This is very discouraging for anyone trying to adopt the framework.
Reference
There is a question here that provides evidence of many of the challenges people have with this.
What does the proposed API look like?
Overview
The ideal solution would be to create a universal
v-href
andv-route
property for all components similar to the way Vue handles@click
on existing components.For example
<ui-button v-href='page.location' />
.This is consistent with Vue's goal of keeping the API small and intuitively close to the Javascript/HTML counterparts that developers are already familiar with.
Context
This will likely require Vue itself (and not just Vue-Router) to change. This would be designed as a full replacement of
router-link
component, with the intention of eventually deprecating router-link.Details
The API for the
v-href
property would be identical to the current router-link "to
" property. All additional prop functionality ofrouter-link
would be handled through an object on thev-route
property. This would behave identically to how a router-link would behave, if the router-link were given both atag
property and (somehow) was able to pass properties/attributes to that tag.Further implementation details will need to be discussed to ensure the intended behavior is fully defined.
The text was updated successfully, but these errors were encountered: