Home » vue » Vue custom directive how to receive a function as params and the function will not auto exec

Vue custom directive how to receive a function as params and the function will not auto exec

Posted by: admin November 26, 2021 Leave a comment

Questions:

How do I receive a function with params in directive like vue v-on?

<div v-example="test(id)"></div>

and this script

methods: {
    test(id) {
        console.log(id);
    }
}

the test function will auto exec, but v-on will not?

Answers:

You may also do the following:

<div v-example="test(id)"></div>

script:

directives: {
  'example': {
    bind(el, binding, vnode) {
      el.addEventListener(binding.arg, (e) => {
        if(binding.value instanceof Function) {
          binding.value();
        }
      })
    }
  } 
},
methods: {
  test(id) {
    let local_id = id;
    return () => {
       console.log(local_id);
    }
  }
}

###

Don’t know how to mimic the built-in v-on style, there’s too many problems includes auto run.

Below is the most concise and simple solution I can think of.

html

<div v-example="function(){ test(id) }"></div>

or more concise

<div v-example="()=>test(id)"></div>

js

directives:{
  example: {
    bind(el, binding){
      binding.value()
    }
  }
},
methods: {
    test(id) {
        console.log(id);
    }
}

###

You can simply pass a function and the parameters separately to your directive like demonstrated on this fiddle. Since passing the function like test('something') will cause it to be evaluated immediately.

Just replace the inserted hook with the one you need: https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments

<div v-demo="{myFunction: test, param: 'something'}"></div>

###

It depends on what you are trying to achieve.
If your goal is to pass the directive a function pointer (so you can execute the function later on inside your directive), you should listen to what gonnavis said and use an arrow function.

What you tried to do will not work because when Vue will mount the component, it will bind the directive to the element (<div>) and create a binding object. This object contains a “value” function which is assigned to return the argument you passed to the directive. So, while the directive is being bound, it calculates the value you passed to it, and if it is a function invocation, it invokes the function immediately.

You can imagine that when the element with your directive is bound, the following line will run:

const binding = {
  value: YOUR_ARG
}

And, in your case, it will be translated to:

const binding = {
  value: test(id)
}

Which will calculate test(id) immediately.

It is all about functional programming.