在我的场景中,我有鼠标悬停和mouseout事件,我想有条件地绑定(例如,仅当用户在具有鼠标的设备上时)。
我意识到我可以在事件处理程序本身中拥有该条件,但仍然会为事件处理程序分配内存,这是不必要的。
有没有办法让事件绑定本身有条件?
(很明显,我想要的是能够使事件订阅短路,因此如果条件为假,则不会发生基础的addEventListener操作)
答案 0 :(得分:7)
在this discussion之后,最好的方法是将v-on绑定到包含您有兴趣订阅的事件的规范对象,并将条件放在那里:
<div v-on="{ mouseover: condition ? handler : null, click: ... }">
一些注意事项:
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 null
和v-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) } : {}"