vue-router: Cannot prevent router-link event
It looks like the click event on the <router-link> is handled before any custom click events:
<router-link to="/b" @click.native.prevent="clicked">should NOT route to b</router-link>
const app = new Vue({
router,
methods: {
clicked: function(e) {
// Does not prevent route change
e.preventDefault()
}
}
})
See working fiddle: https://jsfiddle.net/floorish/zhyqgqpz/
The <router-link> component checks e.defaultPrevented here : https://github.com/vuejs/vue-router/blob/dev/src/components/link.js#L49 , but that is still false when it checks the condition.
Only workaround I’ve found is to capture the event on a parent element (included in fiddle).
Vue version: 2.0.7 Vue-router version: 2.0.2 Possibly related to: https://github.com/vuejs/vue-router/issues/390
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 34 (5 by maintainers)
Commits related to this issue
- Add support for 'disabled' attribute to <router-link>, fixes #916 — committed to bmarkovic/vue-router by deleted user 6 years ago
I think we will add a
disabledprop to<router-link>in the next feature release.@vkruoso good descision! In my case i simplify it like that:
I have a use case where the user must be logged in to access the target page. If the user is not logged in, a modal will show up and the route navigation should be avoided. I could use a button or something else that is not an
atag and userouter.push, but that prevents the browser to open the page on a new tab correctly. I ended up using theeventprop to prevent therouter-linkto listen to the click event. Here is a sample:Where the
routeOrLoginmethod will check if the user is logged in and redirect if so, usingrouter.push, or open the login modal otherwise.+1 for disabled attribute, I really feel that is a simple and easy way to prevent navigation via markup.
I don’t think that’ll solve the following use case:
<router-link event="">works but seems wrong on an idealogical level. it’s highly unnatural both in the reading and the understanding of the result. I honestly don’t understand how the Vue.js crew who mainly focus on readability and simplicity of code would find this “acceptable”.@yyx990803 When will we have the disabled prop to
<router-link>?Has the disabled prop been added, or going to be added? It seems really odd to us that a navigation component does not allow you to directly disable a link.
You can programmatically check the
toroute in the leave hook. Anyway, I think this is just a matter of preference and we’d rather recommend only one way of achieving it for consistency.Why is this issue closed?
I don’t agree that adding a hook just to be able to disable a router link (which would work for buttons in normal HTML) is an acceptable solution, except for the interim. I urge you to reconsider the ‘disabled’ attribute support.
Not to mention that these hooks have no access to the VM and by extension, to application state (which is by far the most likely source of information on whether or not to disable one route) unless one specifically imports global state into the component (which is another batch of dirt, because best practices insist on injecting Vuex and using it through this.$store elsewhere).
Edit: I hope you’ll at least consider my PR. I think it’s not much of a breaking change, as those that use
disabledfor styling purposes on<router-link>and then had to resort to something like:eventto prevent link activation would see no difference (as the change would have no chance to surface), and hardly anyone usesdisabledon elements without a desire to actually disable them.I just encountered this issue. My solution is quite simple. Just wrap the router-link outside of a div, make sure the div span all the width and height of the router-link then finally set @click for the div
& the method:
@yyx990803 Any updates about this? There is a pretty cool Pull Request above.
Fake disabled prop:
instead of:
I don’t think my PR will be merged as there were subsequent patches that were merged or at least got comments and fix requests. I understand that the patch was trivial but the demand was/is real, so this is obviously a design decision by the core team (they do not want this particular option in the router).
I understand that this software needs to meet a common ground between many personal “technical itches” and given how great the Vue experience is due to their adherence to this principle I fully support whatever they choose. The only thing I dislike about it is that there was absolutely no feedback from the powers that be maintainers (even a “sod off, we’re not interested” would be nice, let alone a rationale).
The PR was marked as “intend to implement” a month or so ago.
With the ‘event’ tricks, one just needs to look at the link ‘href’ attribute to get access to the link, or did I miss something? (if you haven’t overridden ‘tag’)
Play with the ‘:disabled’ condition and yes it is programmatic.
@cedric25 that’s not an enforced solution since one just need to remove that css rule to get access to the link ; PR is about deleting the capability to follow the link programmatically
@yyx990803 You can’t check the
toroute in all situations:But I guess in that case you don’t use
<router-link>at all and let the customclickhandler route to the next step?