是否可以在Vue.js中嵌套方法以便对相关方法进行分组?

时间:2016-03-20 00:34:00

标签: javascript methods vue.js namespaces nested

我想将一些Vue.js方法组合在一起的“子方法”类中,但我似乎只能使用单级方法。

例如,如果我想要一组完全处理按钮操作的方法:

new Vue({

    el: '#app',

    data: { },

    methods: {

        buttonHandlers: {

            handler1: function() {
                dosomething;
            },

            handler2: function() {
                dosomething;
            }

        }

    }

});

我希望能够使用类似的东西:

<button v-on:click="buttonHandlers.handler1">Click Me</button>

但没有任何反应。

已经尝试通过添加括号来强制执行该功能:

<button v-on:click="buttonHandlers.handler1()">Click Me</button>

但是我收到此控制台错误:

未捕获的TypeError:scope.buttonHandlers.handler1不是函数

我设置了一个小https://jsfiddle.net/ozx9oc4c/来证明我的意思。

如果有人知道在Vue.js中使用父方法逻辑分组函数的方法,而不是没有真实结构的单级方法的页面和页面,我将不胜感激。

5 个答案:

答案 0 :(得分:4)

我最接近这一点的方法是将父项声明为函数,并使用一组方法返回一个对象。

示例:

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;
        },

      },

    }

  }

});

你可以调用这样的方法:

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

答案 1 :(得分:1)

实际上有一种非常的简单技术:在created钩子中创建嵌套方法:

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

答案 2 :(得分:0)

如果我有这个问题,我会使用click handler()将请求委托给其他方法。 例如:

new Vue({

    el: '#app',

    data: { },

    methods: {

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

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

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


    }

});

并使用html作为

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

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

该代码仅用于演示。 在现实生活中,我将在模板中传递一个数字或字符串参数,并使用switch case来确定处理程序。

答案 3 :(得分:0)

在编写Vue 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:对于官方解决方案,Evan You said no

答案 4 :(得分:0)

我使用这种模式:

模板:

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

脚本:

...
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];
  },
}
...

第二种情况:

脚本:

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);
    },
  }
  ...
}

此外,我认为这不是一个好习惯,但它可以使我的工作更轻松。