Special v-on syntax
by Rahul Kadyan
HTML
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<test v-on="handleEvents">v-on="handleEvents"</test>
<test v-on="'handleEvents'">v-on="'handleEvents'"</test>
<test v-on="[handleEvents, handleEvents2]">v-on="[handleEvents, handleEvents2]"</test>
<test v-on="['handleEvents', 'handleEvents2']">v-on="['handleEvents', 'handleEvents2']"</test>
<test v-on="{ action: handleAction }">v-on="{ action: handleAction }"</test>
<test v-on="{ action: 'handleAction' }">v-on="{ action: 'handleAction' }"</test>
<test v-on="['handleEvents', { action: 'handleAction' }]">v-on="['handleEvents', { action: 'handleAction' }]"</test>
<test v-on="handlers">v-on="handlers"</test>
<pre>handlers: {{ handlers | json }}</pre>
<pipe v-on="handleEvents">Pipe</pipe>
</div>
CSS
button {
background: #40b883;
color: white;
font-size: 12px;
font-family: monospace;
border: none;
border-radius: 3px;
padding: 10px 12px;
margin: 12px;
cursor: pointer;
}
button:hover {
background: #7cd1ab;
}
pre {
margin: 12px;
}
JavaScript
const SpecialVOn = {
install (Vue) {
const superEmit = Vue.prototype.$emit
Vue.prototype.$emit = function (event, ...args) {
superEmit.call(this, event, ...args)
if (this._events.$all) {
for (let k in this._events.$all) {
this._events.$all[k].forEach(cb => {
cb.call(this, event, ...args)
})
}
}
}
function removeItem (array, item) {
const index = array.indexOf(item)
if (index !== -1) {
array.splice(index, 1)
}
}
function getMethod (vnode, value) {
let fn
if (typeof value === 'function') {
fn = value
} else if (typeof value === 'string') {
fn = vnode.context[value]
}
return fn
}
function $on (vnode, event, value) {
const fn = getMethod(vnode, value)
if (fn) {
vnode.child.$on(event, fn)
}
}
function $off (vnode, event, value) {
const fn = getMethod(vnode, value)
if (fn) {
vnode.child.$off(event, fn)
}
}
function getCbs (vnode) {
const vm = vnode.child
const uid = vnode.context._uid
const $all = (vm._events.$all || (vm._events.$all = {}))
const cbs = ($all[uid] || ($all[uid] = []))
return cbs
}
function addCbs (vnode, value) {
const cbs = getCbs(vnode)
if (typeof value === 'function' || typeof value === 'string') {
const fn = getMethod(vnode, value)
if (fn) {
cbs.push(fn)
}
} else if (Array.isArray(value)) {
value.forEach(cb => {
addCbs(vnode, cb)
})
} else if (typeof value === 'object') {
for (let k in value) {
const currentValue = value[k]
if (Array.isArray(currentValue)) {
currentValue.forEach(v => {
$on(vnode, k, v)
})
} else {
$on(vnode, k, currentValue)
}
}
}
}
function removeCbs...