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
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.
export default {
created () {
// How to call the "nested" method
this.dummy('init')
// Pass arguments
this.dummy('greet', {'name': 'John'})
},
// Namespaced methods
methods: {
dummy (name, conf) {
// you can access reactive data via `that` reference,
// from inside your functions
const that = this
return {
'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.
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() {
var self = 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>
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) { return self.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:
const fabric = (arg, foo, context) => {
const methods = foo(context);
if (!Object.keys(methods).includes(arg)) return () => false;
return methods[arg];
};
export default {
...
methods: {
test () {
this.info('open')('test');
},
info (arg) {
console.table({omg: [arg, '!']});
},
example (arg) {
return fabric(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.
There is actually a very simple technique: create your nested methods in the created
hook:
created() {
this.on = {
test: () => {console.log(this)}
}
this.on.test();
}
if i had that problem, i would use a click handler() to delegate request to other methods. eg:
new Vue({
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
<button v-on:click="buttonHandler(handler1)">Click Me</button>
<button v-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.