Reputation: 327
I used a form component of a Third Party Component Library, which hasn't disabled props, and I bind a click event to every form item via @click to popup a dialog when the form item was clicked. But here is my problem, in some case the form item should not be clickable, so I create a custom prevent-click directive which like this:
const clickHandler = e => {
e.stopImmediatePropagation()
e.stopPropagation()
return false
}
const directive = {
bind(el, { value }) {
if (value) {
el.addEventListener('click', clickHandler, true)
}
},
update(el, { value }) {
if (!value) {
el.removeEventListener('click', clickHandler, true)
} else {
el.addEventListener('click', clickHandler, true)
}
}
}
used like this:
<form-item v-prevent-click="true" @click="showDialog"></form-item>
The prevent-click directive do nothing but add a captured event listener to the form-item, which stop the propagation, everything goes well so far, but the problem is that the form-item has a pseudo child element which is added by css after selector. So when I clicked the pseudo child element, due to the pseudo child element itself doesn't dispatch the click event instead of the form-item, so the form-item element will still dispatch the event, besides the vue builtin directive @click event handler was bound first, which result in the useCapture param of addEventListener method won't effect.
In the 1.x version, there is priority option of custom directive, but the 2.X remove it. So are there anyway to make my custom directive bind before than the builtin @click?
Upvotes: 1
Views: 1730
Reputation: 63
You should use Vue's built-in event modifiers (reference here). Try this:
<form-item @click.stop.prevent="showDialog"></form-item>
I don't know what your third-party components framework is, but if you really need to handle the preventDefault
by yourselft, I suggest you to do the following:
Template
<form-item @click="showDialog"></form-item>
Script
methods: {
showDialog(e) {
e.preventDefault();
// Your code to display dialog...
}
}
If you also need to pass arguments to showDialog
, remember that you can - just pass the event as first argument:
<form-item @click="showDialog($event, urData)"></form-item>
Upvotes: 1
Reputation: 20970
Consider passing a flag to showDialog
. If you cannot modify showDialog
function wrap it in another function:
// Your compoennt template
<form-item @click="wrappedShowDialog(true)"></form-item>
// Vue.js component
wrappedShowDialog(isAllowed) {
if (isAllowed) {
this.showDialog();
}
}
Upvotes: 0