One of the main distinctions lies in the scope access. The scope bound to `onclick` is global, requiring the functions it calls to be accessible from the global scope. On the other hand, `v-on`'s scope is the Vue model.
Another notable feature is Vue's user-friendly API for defining custom events using `vm.$emit()`. It is also straightforward to listen for these events by using `v-on:customevent="callback"`, which can be easily related to a hypothetical `onfizz="callback()"`.
Considering this, it would be logical to introduce `v-on:click` for a consistent API alongside the other extensions offered by `v-on`.
/*
* This pollutes scope. You would have to start
* making very verbose function names or namespace your
* callbacks so as not collide with other handlers that
* you need throughout your application.
*/
function onClickGlobal() {
console.log("global");
}
const fizzbuzz = {
template: "<button @click='onClick'>FizzBuzz</button>",
methods: {
onClick() {
this.$emit("fizz");
}
}
};
const app = new Vue({
el: "#app",
components: {
fizzbuzz
},
methods: {
onClickModel() {
console.log("model");
},
onFizz() {
console.log("heard fizz");
}
}
});
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app">
<section>
<h2>Buttons and Clicks</h2>
<!-- Calling function of the bound scope -->
<button @click="onClickModel">v-on Model</button>
<!-- Works as well, but calls the global -->
<button @click="onClickGlobal">v-on Global</button>
<!-- You need to explicitly invoke the function from onclick -->
<!-- This won't work because onClickModel isn't global -->
<button onclick="onClickModel()">onclick Model</button>
<!-- Works because onClickGlobal is global -->
<button onclick="onClickGlobal()">onclick Global</button>
<!-- You can technically call onClickModel through the global app -->
<!-- but you really shouldn't -->
<!-- Works because app.onClickModel is technically global -->
<button onclick="app.onClickModel()">onclick Global through app.onClickModel</button>
</section>
<section>
<h2>Custom Events</h2>
<fizzbuzz @fizz="onFizz"></fizzbuzz>
<!-- The element below doesn't work -->
<button onfizz="onClickGlobal">Hypothetical Fizz</button>
</section>
</div>