calling method dynamically through variables in vuejs

Amit Sharma picture Amit Sharma · Jan 16, 2018 · Viewed 11.5k times · Source

Is it possible to call the method through variables? I have drag and drop elements having ID and according to id I have to call the method. Consider the following Eg.

<template>
   <div>
    <div id="draggable">
      <div class="draggable" id="db">Step2</div>
      <div class="draggable" id="spstep"> Step</div>
      <div class="draggable" id="merge">Merge</div>
      <div class="draggable" id="copy">copy</div>
    </div>
     <div id="id="draggable"">Drop Here</div>
   </div>
 </template> 

<script>
  export default {

  data () {

   }
  mounted () {
  var _this = this
  $(".draggable").draggable({
     grid: [ 20, 20 ],
     appendTo: '#droppable',
     // containment: "window",
     cursor: 'move',
     revertDuration: 100,
     revert: 'invalid',
     helper: 'clone',
     refreshPositions: true,
     scroll: true,
     containment: "document",
      zIndex: 10000,
 });

 $("#droppable").droppable({
     accept: ".draggable",
     tolerance: "intersect",
     drop: function (event, ui) {         
       var leftPosition  = pos.left;//ui.offset.left - $(this).offset().left;
       var topPosition   = pos.top;//ui.offset.top - $(this).offset().top;
       console.log(leftPosition + "  "+ topPosition);
       var type = ui.draggable.attr("id");

       //Here call methods according to id of draggable element
       //like 
       //current implement which is not enhanced code
       if(type == 'db')
          _this.db()

       if(type == 'spstep')
          _this.spstep()

       if(type == 'merge')
          _this.merge()

       if(type == 'copy')
          _this.copy()   
        //desired implementation alike
        _this.[type]() // this syntax is wrong and throws an error  
       }
     }); 
 }
 methods: {
  db(){
    //db called do something
  }
  spstep(){
    //spstep called do something
  }
  merge(){
    //merge called do something
  }
  copy(){
    //copy called do something
  }
}
</script>
<style>
</style>

Above is my sample code in which I have mentioned my requirements in comments.I want to call the methods according to dragged element. I don't know even this is possible but by this approach, I can reduce lots of unwanted code.

Any help would be highly appreciated
Thanks

Answer

throrin19 picture throrin19 · Jan 16, 2018

In Javascript if you are an object like this :

const foo = {
    bar() {},
    baz() {}
};

To call this "dynamicly" you should type

foo['bar']()
foo['baz']()

So, in your case, instead of :

this.[type]()

You should type :

this[type]()

Object could be manipulated like array index but, in this case, indexes are juste the fields

Warning : Your $.droppable().drop function is not correctly binded. So, at this time, the this is not the VueJS component :

  • in basics functions/methods of your vuejs component use the es6 functions fields (like your mounted, ...).
  • Inside this functions, use arrow function to kepp the right context for this. In this example, your drop function must be an arrow function to work correctly