Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I capture click event on custom directive on Vue.js?

I am trying to learn Vue.js and came to an practice example where I need to implement a custom directive whice works lice 'v-on'. This means that i need to capture the click event on my custom directive and call a method.

The template i was thinking of.

<template>
    <h1 v-my-on:click="alertMe">Click</h1>
</template>

The problem is i don't know how to capture the click event in the custom directive. Excuse the clumsy code below.

<script>
    export default {
        methods: {
            alertMe() {
                alert('The Alert!');
            }
        },
        directives: {
            'my-on': {
                bind(el, binding, vnode) {
                    console.log('bind');

                    el.addEventListener('click',()=>{
                        console.log('bind');
                        vnode.context.$emit('click');
                    });
                },

            }
        }
    }
</script>

Can anyone help me understand how this works? I didn't manage to find any example of something similar.

like image 838
Vlad Avatar asked Nov 30 '22 22:11

Vlad


2 Answers

After some more searching i came to this solution:


<template>
  <h1 v-my-on:click="alertMe">Click me!</h1>
</template>

<script>

  export default {

    methods: {

      alertMe() {

        alert('The Alert!');

      }

    },

    directives: {

      'my-on': {

        // Add Event Listener on mounted.
        bind(el, binding) {
          el.addEventListener(binding.arg, binding.value);
        },

        // Remove Event Listener on destroy.
        unbind(el, binding) {
          el.removeEventListener(binding.arg, binding.value);
        }

      }

    }

  }
</script>
like image 97
Vlad Avatar answered Dec 04 '22 06:12

Vlad


The solution you found is, as far as I can tell, the very best solution for what you are looking for. However, for those who don't know much about Vue.JS I thought I'd give a quick explanation. I'd also suggest you check out the official Vue documentation for Custom Directives or my Medium article on the concepts.

This is the code that Vlad came to and I would support:

<template>
    <h1 v-my-on:click="alertMe">Click me!</h1>
</template>

<script>
    export default {
        methods: {
            alertMe() {
                alert('The Alert!');
            }
        },
        directives: {
            'my-on': {
                bind(el, binding) {
                    let type = binding.arg;
                    let myFunction = binding.value;
                    el.addEventListener(type, myFunction);
                }
            }
        }
    }
</script>

In short, Vue Directives are called on the lifecyle of the element they are attached to, based on the directive object definition. In the example the function defined is called "bind" so the directive will call that function when the element is bound into the DOM.

This function receives the element it's attached to "el" and the different content of the directive usage in the template "binding". In the binding usage in the template, the value after the colon ":" is the "arg" which in this example is the string literal "click". The value inside of the quotes '""' is the "value" which in this case is the object reference to the function "alertMe".

The vars that are defined by getting binding.arg and binding.value (with their respective content) can then be used to create an event listener contained inside of the element "el" that the directive is used on (el is modifiable). So, when the element is created and bound, this new event listener is created on the "click" event defined by "arg" and it will call the "alertMe" function defined by "value".

Because the modification is contained inside the element, you don't have to worry about cleaning up on unbind, because the listener will be destroyed when the element is destroyed.

And that is a basic description of what is happening in the suggested code. To see more about directives and how to use them, follow the suggested links. Hopefully that helps!

like image 25
Marcus Smith Avatar answered Dec 04 '22 06:12

Marcus Smith