Vue.directive('login-to-click', {
bind (el) {
const clickHandler = (event) => {
event.preventDefault()
event.stopImmediatePropagation()
alert('click')
}
el.addEventListener('click', clickHandler, true)
}
})
usage
<button @click="handleClick" v-login-to-click>CLICK</button>
handleClick
is always triggered. How I can prevent that from directive? Tried with/without addEventListener "capture" flag without any luck.
For now I ended up with following solution:
Vue.prototype.$checkAuth = function (handler, ...args) {
const isLoggedIn = store.getters['session/isLoggedIn']
if (isLoggedIn) {
return handler.apply(this, args)
} else {
router.push('/login')
}
}
And then in component
<button @click="$checkAuth(handleClick)">CLICK</button>
preventDefault() or event. stopPropagation() inside event handlers. It is always better to have your methods deal purely with data logic instead of having to deal with DOM event details. Vue provides us with some event modifiers for the v-on.
preventDefault() prevents the default browser behavior for a given element. stopPropagation() stops an event from bubbling or propagating up the DOM tree. Whereas, return false is a combination of both preventDefault() and stopPropagation() .
Prevent default behaviorTo prevent an event's default behavior, we can call the . prevent modifier in Vue, which calls the native event. preventDefault() method. This series of steps prevents the event from reloading the page after the form is submitted.
stopPropagation() The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases. It does not, however, prevent any default behaviors from occurring; for instance, clicks on links are still processed.
From my understanding those are two different event handlers, you are only preventing the default event of the one bound in the directive, this has no influence on @click
however, because you are not overwriting the click listener but adding a second one.
If you want the default of your @click binding to be prevented you can use @click.prevent="handleClick"
.
I don't think there's any way to do it from the directive, since you explicitly add another listener by binding @click
to the button.
in my app I have many buttons (follow/like/add to watchlist/block etc) that require user to be logged in to click on them
As with many things in Vue 2, this is a bad use case for a directive, but a very good use case for a component.
Here is a button that is only clickable when the user is authorized.
console.clear()
const AuthenticatedButton = {
props:["onAuth", "onNonAuth", "disable", "auth"],
template: `
<button @click="onClick"
:disabled="disableWhenNotAuthorized">
<slot>{{this.auth}}</slot>
</button>`,
computed:{
disableWhenNotAuthorized(){
return this.disable && !this.auth
}
},
methods:{
onClick(){
if (this.auth && this.onAuth) this.onAuth()
if (!this.auth && this.onNonAuth) this.onNonAuth()
}
}
}
new Vue({
el:"#app",
data:{
loggedIn: false
},
methods:{
onClick(){
alert("User is authenticated")
},
notAuthorized(){
alert("You are not authorized.")
}
},
components:{
"auth-btn": AuthenticatedButton
}
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<h3>User is {{!loggedIn ? 'Not Authorized' : 'Authorized'}}</h3>
<auth-btn :auth="loggedIn"
:on-auth="onClick"
:on-non-auth="notAuthorized">
Executes non auth handler when not authorized
</auth-btn> <br>
<auth-btn :auth="loggedIn"
:on-auth="onClick"
:disable="true">
Disabled when not authorized
</auth-btn> <br><br>
<button @click="loggedIn = true">Authenicate User</button>
</div>
With this button you can set an authorized handler and a non-authorized handler. Additionally, you can just disable the button if the user is not authorized.
In this component the authorized state is passed in through a property, but if you were using some form of state management (like Vuex) you could just as easily use that instead.
https://v2.vuejs.org/v2/guide/events.html#Event-Modifiers
There are a couple modifiers. .prevent
is what I was looking for
<a href="#" @click.prevent="sendMessage('just one click');">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With