将多个事件绑定到Vue中的v-on指令

时间:2018-12-18 01:36:54

标签: javascript jquery vue.js vuejs2

在jQuery中,您可以通过执行以下操作来绑定多个事件:

$('#myDiv').on('touchstart mousedown', // more code here

据我了解,这将同时监听touchstartmousedown。但是我不知道如何用Vue做同样的事情。我只能做@touchstart="doSomething()"@mousedown="doSomething()"。我是否缺少明显的东西?谢谢

3 个答案:

答案 0 :(得分:2)

1。带有事件修饰符

如果您依赖event,则可以尝试与event modifiers绑定,并以内联方式对其进行链接。像这样:

<a @click.stop="doThis" @click.right="showContextMenu"></a>

2。以编程方式附加事件

或者,您可以创建事件列表及其各自的实现以附加到v-on并与之进行循环,这是this post的一种解决方法:

created() {
    const EVENTS = [
      {name: 'my-event1', callback: () => console.log('event1')},
      {name: 'my-event2', callback: () => console.log('event2')},
      {name: 'my-event3', callback: () => console.log('event3')}
    ]

    for (let e of EVENTS) {
      this.$on(e.name, e.callback); // Add event listeners
    }
  }

<button @click="$emit('my-event1')">Raise event1</button>
<button @click="$emit('my-event2')">Raise event2</button>
<button @click="$emit('my-event3')">Raise event3</button>

3。 v-on多个值

否则,就像可以执行v-bind on multiple values一样,实际上也可以对v-on执行相同的操作。

<div id="mydDiv" v-on="handlers"></div>

// ...

data() {
  const vm = this;

  return {
    handlers: {
      mousedown: vm.divMousedown,
      touchstart: vm.divTouchstart
    }
  }
},

methods: {
  divMousedown() {
    console.log('event: mousedown');
  },
  divTouchstart() {
    console.log('event: touched');
  }
}

如果您需要按事件类型细分处理程序,请尝试检查type while the event is being fired,因此在您的情况下,由于touchstart似乎也会触发mousedown,也许:

methods: {
  onTouched(evt) {
    evt.preventDefault();

    if (evt.type === 'mousedown') {
        // handle mousedown
    }
    else if (evt.type === 'touchstart') {
        // ...
    }
  }
}
  

Note:您可能想在preventDefault()而不是touchmove上致电touchstart。这样,鼠标事件仍然可以触发,并且诸如链接之类的东西将继续起作用。

答案 1 :(得分:1)

由于inherent limitations in attribute names and the desire to avoid runtime overhead.

,vue故意不支持绑定到多个事件

如果绝对必须具有多事件绑定,请a custom directive would be the way to go

(以下代码是从链接的JSFiddle中无耻复制的,因为SO不允许在没有代码的情况下链接到小提琴)

function functionWrapper(e) {
  /* add filters to handle event type before propagating to callback function for custom event handler */
  e.target.__handler__.fn(e)
}

Vue.directive('multiEvent', {
  bind: function(el, binding, vnode) {
    el.__handler__ = binding.value
    binding.value.evt.forEach(e => el.addEventListener(e, functionWrapper))
  },
  unbind: function(el, binding) {
    el.__handler__.evt.forEach(e => el.removeEventListener(e, functionWrapper))
    el.__handler__ = null
  }
})

用法:

<input v-multi-event="{ evt: ['click', 'blur', 'change', 'keydown'], fn: someCallback }">

答案 2 :(得分:1)

不,您没有丢失任何明显的内容。 jQuery为方便起见,“ touchstart mousedown”是一种简写形式。 Vue没有提供类似的便利(可能是因为使用所有提供的选项,attrs的事件绑定语法已经变得非常繁琐了)。

正确的方法将如您所述,使用两个单独的属性:@touchstart="doSomething()" or @mousedown="doSomething()"