Skip to content
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

Feature: use v-on:click with v-link #390

Closed
weotch opened this issue Feb 26, 2016 · 10 comments
Closed

Feature: use v-on:click with v-link #390

weotch opened this issue Feb 26, 2016 · 10 comments

Comments

@weotch
Copy link

weotch commented Feb 26, 2016

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>
@weotch
Copy link
Author

weotch commented Feb 26, 2016

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

@weotch
Copy link
Author

weotch commented Feb 26, 2016

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.

@perkola
Copy link

perkola commented Mar 6, 2016

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.

@repsac-by
Copy link

I think it is better to use Transition Hooks

route: {
  canDeactivate(transition) {
    transition.abort()
  }
}

@rpkilby
Copy link

rpkilby commented Mar 7, 2016

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.

@perkola
Copy link

perkola commented Mar 9, 2016

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.

@Gomah
Copy link

Gomah commented Mar 10, 2016

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

@weotch
Copy link
Author

weotch commented Mar 10, 2016

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

@Gomah
Copy link

Gomah commented Mar 10, 2016

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.

@paulpflug
Copy link

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.

paulpflug added a commit to paulpflug/vue-router that referenced this issue Apr 4, 2016
has to be lower than `v-on` - 700
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants