Skip to content

Instantly share code, notes, and snippets.

@iShawnWang
Last active November 1, 2023 07:26
Show Gist options
  • Save iShawnWang/b58972d5b25c2a74ad5c95a7f1672c62 to your computer and use it in GitHub Desktop.
Save iShawnWang/b58972d5b25c2a74ad5c95a7f1672c62 to your computer and use it in GitHub Desktop.
v-track
// Sample Usage
<template>
<button v-track="xxxEvent" />
<input v-track="xxxEvent" />
<input v-track="() => new Date().getTime()" />
</template>
<script>
// v-track directive
Vue.directive("track", {
bind: function (el, binding, vnode) {
const _listener = () => {
if(typeof binding.value === 'string'){
Vue.track(binding.value);
}else if(typeof binding.value === 'function'){
Vue.track(binding.value())
}
};
const _event = binding.arg || matchEventForElement(el)
if (vnode.componentInstance) {
vnode._track_event = _event
vnode._vtrack_listener = _listener;
vnode.componentInstance.$on(_event, _listener);
} else {
el._track_event = _event
el._vtrack_listener = _listener;
el.addEventListener(binding.arg, _listener);
}
},
unbind(el, binding, vnode) {
if (vnode.componentInstance) {
vnode.componentInstance.$off(vnode._track_event, vnode._vtrack_listener);
} else {
el.removeEventListener(el._track_event, el._vtrack_listener);
}
},
});
const matchEventForElement = (el) => {
if (!el) {
return;
}
if (el.tagName) {
if (["button", "label"].includes(el.tagName)) {
return "click";
}
if (["input", "select"].includes(el.tagName)) {
return "focus";
}
}
if (el.className) {
if (/input|select|date/.test(el.className)) {
return "focus";
}
if (/button|label|radio|checkbox/.test(el.className)) {
return "click";
}
}
};
const _track = (msg) => {
// your track function here
console.log(`[track]:`, msg);
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment