Skip to content Skip to sidebar Skip to footer

Is It Possible To Nest Methods In Vue.js In Order To Group Related Methods?

I'd like to group some of my Vue.js methods together in a sort of 'submethod' class, but I only seem to be able to have single level methods. For example, if I wanted to have a set

Solution 1:

The closest I've got to doing this, is to declare the parent as a function, and return an object with a set of methods.

Example:

new Vue({

  el: '#app',

  data: {},

  methods: {

    buttonHandlers: function() {
      varself = this; // so you can access the Vue instance below.return {

        handler1: function() {
          dosomething;
          self.doSomething();
        },

        handler2: function() {
          dosomething;
        },

      },

    }

  }

});

And you can call the methods like this:

<button @click="buttonHandlers().handler1()">Click Me</button>

Solution 2:

There is actually a very simple technique: define your nested methods in the created hook:

created() {
  this.on = {
    test: () => {console.log(this)}
  }
  this.on.test();
}

NOTE: Two things, A) in this case you must use arrow function(s) and B) if this feels "hacky" to you, perhaps because of the cluttering of the created lifecycle hook, you can always delegate to a method, let's say this.namespaceMethods(), e.g.:

created() {
  this.namespaceMethods();
  // call namespaced methodsthis.foo.bar();
  this.foobar.baz();
  // etc.
},
methods: {
  this.namespaceMethods() {
    this.foo = {
      bar: () => {console.log("foobar")}
    },
    this.foobar = {
      baz: () => {console.log("foobarbaz")}
    }
  },
  // etc
}

Solution 3:

if i had that problem, i would use a click handler() to delegate request to other methods. eg:

newVue({

    el: '#app',

    data: { },

    methods: {

        handler1: function() {
             console.log("handler 1 called");
        },

        handler2: function() {
            console.log("handler 2 called");
        },

        buttonHandler:function(callback){
            callback();
        }


    }

});

and use html as

<buttonv-on:click="buttonHandler(handler1)">Click Me</button><buttonv-on:click="buttonHandler(handler2)">Click Me</button>

The code is only for demo. In real life i will be passing a number or string argument in template and using switch case to determine handler.

Solution 4:

I had the same issue (the need of a namespace) while writing a Vue mixin. This answer doesn't directly address your case, but it could give a clue.

This is how I defined the mixin.

exportdefault {
   created () {
    // How to call the "nested" methodthis.dummy('init')

    // Pass argumentsthis.dummy('greet', {'name': 'John'})
   },

   // Namespaced methodsmethods: {
     dummy (name, conf) {
       // you can access reactive data via `that` reference,// from inside your functionsconst that = thisreturn {
         'init': function (conf) {
            console.log('dummy plugin init OK')
         },
         'greet': function (conf) {
            console.log('hello, ' + conf['name'])
         }
       }[name](conf)
     }
   }
 }

PS: for an official solution, Evan You said no.

Solution 5:

I use this pattern:

Template:

<ExampleComponent
  :test="hello"@close="(arg) => example('close')(arg)"@play="(arg) => example('next')(arg)"@stop="(arg) => example('back')(arg)"/>

Script:

...
methods: {
  test () {
    this.info('open')('test');
  },
  info (arg) {
    console.table({omg: [arg, '!']});
  },
  example (arg) {
    let self = this;
    const methods = {
      open (arg) {self.info(arg);},
      close (arg) { returnself.example('play')(arg)},
      play (arg) {console.log(self, this)},
      stop () {console.error('Lo1')},
    };
    if (!Object.keys(methods).includes(arg)) return () => false;
    return methods[arg];
  },
}
...

And second case:

Script:

constfabric = (arg, foo, context) => {
  const methods = foo(context);
  if (!Object.keys(methods).includes(arg)) return() =>false;
  return methods[arg];
};

exportdefault {
  ...
  methods: {
    test () {
      this.info('open')('test');
    },
    info (arg) {
      console.table({omg: [arg, '!']});
    },
    example (arg) {
      returnfabric(arg, (cnx)=>({
        open (arg) {cnx.info(arg);},
        close (arg) { return cnx.example('play')(arg)},
        play (arg) {console.log(cnx, this)},
        stop () {console.error('Lo1')},
      }), this);
    },
  }
  ...
}

Also, I think this is not a good practice, but it works and makes my work easier.

Post a Comment for "Is It Possible To Nest Methods In Vue.js In Order To Group Related Methods?"