This doesn't appear to work:
<a v-link='{name: "home"}' v-on:click='onClick'>Home</a>
I think it's this e.preventDefault(). I get why that's there, but can you think of some way we can also handle these clicks from the Component? Maybe a callback could be specified in v-link, like:
<a v-link='{name: "home"}, onClick'>Home</a>
<a v-link='{name: "home", click: onClick}'>Home</a>
Another option might be to give v-on a higher priority. I'm currently looking into whether I can adjust the priority of an internal directive...
FYI, this approach to reducing the v-link priority is working for me so far:
onPriority = Vue.directive('on').priority
Vue.directive('link').priority = onPriority - 1
Vue.directive('link-active').priority = onPriority - 2
Note to anyone else doing this, the above code needs to run before your components are compiled.
An idea is that the object passed to v-link could have some kind of callback property where you could specify a function on the component to execute.
I think it is better to use Transition Hooks
route: {
canDeactivate(transition) {
transition.abort()
}
}
I think it is better to use Transition Hooks
That doesn't seem like the correct responsibility. The transition hook is there to determine whether or not you can deactivate the current route. I would not want to shove my event handling code inside that. eg,
<a v-link='{name: "home"}'>Cancel</a>
<a v-link='{name: "home"}' v-on:click='saveTheThing'>Save</a>
In both cases I'm navigating back to the main page, but canceling and saving are two distinct actions.
I agree with @rpkilby. A use case is a hamburger menu component with v-link to some route. When a link is clicked the menu should collapse (preferably with something like v-on:click.prevent='collapseMenu()') before transitioning into the new route.
This _can_ be achieved with transition hooks that collapses the menu on each activate but that results in code duplication since every route has to invoke the collapseMenu() function on the hamburger menu component.
Edit: with a callback in the v-link directive, the collapseMenu() could be invoked from there.
In HTML5 history mode, v-link will intercept the click event so that the browser doesn't try to reload the page.
I don't really see the problem here, it makes sense that v-link prevents the default behaviour, you can use a simple method to improve it :)
<a @click.prevent="navigateTo('home')">Home</a>
Use a method instead:
navigateTo: function (nav) {
// Do what you want here.
// this.saveTheThing()
this.$router.go({
path: nav
})
}
@Gomah with that approach you lose both v-link creating an href (which I want for SEO) and the setting of the v-link-active class.
You can still specify an href as the @click.prevent will prevent it anyway.
For the v-link-active class, you can specify it in your method but indeed, it would be easier then to have a higher priority on v-on so you don't have to rewrite the v-link behaviour yourself in your method.
the problem isn't the e.preventDefault() but the next line: this.router.go(target)
This will navigate the browser and stop the event bubbling.
a nice solution would be:
<a v-link='{name: "home"}' v-on:click.capture='onClick'>Home</a>
just make sure you don't use event.stopPropagation() within your onClick
besides that it would make sense to lower the priority of v-link as a click on it normally is terminal.
Most helpful comment
I agree with @rpkilby. A use case is a hamburger menu component with
v-linkto some route. When a link is clicked the menu should collapse (preferably with something likev-on:click.prevent='collapseMenu()') before transitioning into the new route.This _can_ be achieved with transition hooks that collapses the menu on each
activatebut that results in code duplication since every route has to invoke thecollapseMenu()function on the hamburger menu component.Edit: with a callback in the
v-linkdirective, thecollapseMenu()could be invoked from there.