条件事件绑定 - vuejs

时间:2017-12-31 12:03:52

标签: events vue.js

在我的场景中,我有鼠标悬停和mouseout事件,我想有条件地绑定(例如,仅当用户在具有鼠标的设备上时)。

我意识到我可以在事件处理程序本身中拥有该条件,但仍然会为事件处理程序分配内存,这是不必要的。

有没有办法让事件绑定本身有条件?

(很明显,我想要的是能够使事件订阅短路,因此如果条件为假,则不会发生基础的addEventListener操作)

6 个答案:

答案 0 :(得分:7)

this discussion之后,最好的方法是将v-on绑定到包含您有兴趣订阅的事件的规范对象,并将条件放在那里:

<div v-on="{ mouseover: condition ? handler : null, click: ... }">

一些注意事项:

  • 为处理程序传递 null 表示基础addEventLisetener发生 - 这就是我们想要的
  • 这意味着将所有活动订阅分组到一个v-on中 属性而不是将其拆分为单独的和显式的 绑定(<div @mouseover='...' @click='...'/>

  • 如果这是一个长期存在的组件,基础数据会发生变化 经常(导致重新绑定)你应该注意 处理订阅(即相应的removeEventListener)作为在一个绑定传递中进行的订阅 不会在随后的处理中被处置。根据你的评估 用例......

答案 1 :(得分:1)

如果你想做类似的事情,你可以通过在要应用事件的ref上添加element来手动应用事件监听器,然后使用它来绑定事件监听器如果符合条件,则在mounted钩子中:

<强>标记

<button ref="button">
  Mouse Over Me
</button>

Vue实例

new Vue({
  el: '#app',
  mounted() {
    let hasMouse = true;

    // If the user has a mouse, add the event listeners
    if (hasMouse) {
      let button = this.$refs.button

      button.addEventListener('mouseover', e => {
        this.mouseover = true
      })

      button.addEventListener('mouseout', e => {
        this.mouseover = false
      })
    }

  },
  data: {
    mouseover: false
  }
})

这是一个JSFiddle:https://jsfiddle.net/0fderek6/

如果你不喜欢这种方法,你也可以使用directive并将条件放在那里,然后你可以将它放在mixin中以使其可重复使用:

<强>密新

const mouseEvents = {
  directives: {
    mouseEvents: {
      bind(el, binding, vnode) {
        let hasMouse = true;

        if (hasMouse) {
          el.addEventListener('mouseover', e => {
            vnode.context.mouseover = true
          })

          el.addEventListener('mouseout', e => {
            vnode.context.mouseover = false
          })
        }
      }
    }
  },
  data: {
    mouseover: false
  }
}

Vue实例

new Vue({
  el: '#app',
  mixins: [mouseEvents]
})

<强>标记

<button v-mouse-events>
  Mouse Over Me
</button>

这是JSFiddle:https://jsfiddle.net/nq6x5qeq/

修改

如果您喜欢directive方法,那么您需要做的就是添加unbind挂钩以删除侦听器,然后您可以将binding arg作为事件类型和{ {1}}是处理程序:

binding value

现在您需要做的就是像添加Vue.directive('mouse', { bind(el, binding) { if (hasMouse) { console.log(binding.arg + ' added') // bind the event listener to the element el.addEventListener(binding.arg, binding.value) } }, unbind(el, binding) { if (hasMouse) { console.log(binding.arg + ' removed') el.removeEventListener(binding.arg, binding.value) } } }); 一样添加每个侦听器:

v-bind

这是JSFiddle向您展示它是如何工作的:https://jsfiddle.net/59ym6hdb/

答案 2 :(得分:1)

此版本自Vue 2.6起有效:

<div
  @mouseover="enableMouseover ? mouseOverHandler : null"
  @click="enableClick ? clickHandler : null"
  ...
>
  

事件解析为null时,绑定将被删除。

https://github.com/vuejs/vue/issues/7349#issuecomment-458405684

答案 3 :(得分:1)

这就是我正在使用的:

v-on="condition ? { click: handler } : {}"Reference

我得到Invalid handler for event "click": got nullv-on="{ click: condition ? handler : null }"

答案 4 :(得分:1)

条件事件绑定的工作原理如下:

<div @[event]="handler" />

当事件解析为 null 时,绑定将被删除。

(直接来自 https://github.com/vuejs/vue/issues/7349#issuecomment-458405684

示例:

<template>
  ...
  <span @[mayclick]="onClick">...</span>
  ...
</template>

<script>
export default {
  ...
  computed: {
    mayclick: function() {
      return this.isClickable ? "click" : null;
    }
  },
  methods: {
    onClick: function (message) {
      ...
    }
  }
}

答案 5 :(得分:0)

如果收到“事件“点击”无效的处理程序:获取空”错误,并且处理程序函数需要一些参数,则应将处理程序包装在函数中。

所以这个>

https://repo.spring.io/release

代替

v-on="condition ? { blur: () => handler(params) } : {}"