One of the best ways to see how .prevent and .self interact is looking at the output of the Vue compiler:
.prevent.self:
on: {
"click": function($event){
$event.preventDefault();
if($event.target !== $event.currentTarget)
return null;
logger($event)
}
}
.self.prevent
on: {
"click": function($event){
if($event.target !== $event.currentTarget)
return null;
$event.preventDefault();
logger($event)
}
}
The key difference between those 2 code blocks is inside the fact that the order of the operations matters, a .prevent.self will prevent events coming from its children, but doesn't run any code, but a .self.prevent will only cancel events directly created by itself, and ignores child requests completely.
Demo:
var app = new Vue({
el: '#appp',
data: {log:[]},
methods: {
logger(arg) {
this.log.push(arg);
}
}
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="appp" style="display: flex; flex-direction: row;">
<form @submit.prevent="logger('form')" style="width: 50%;">
<button>
<p @click.prevent.self="logger('prevent.self')">
prevent.self
<span>(child)</span>
</p>
<p @click.self.prevent="logger('self.prevent')">
self.prevent
<span>(child)</span>
</p>
<p @click.prevent="logger('prevent')">
prevent
<span>(child)</span>
</p>
<p @click.self="logger('self')">
self
<span>(child)</span>
</p>
<p @click="logger('none')">
none
<span>(child)</span>
</p>
</button>
</form>
<pre style="width: 50%;">{{log}}</pre>
</div>
</div>