Javascript 在 Vue.js 中监听自定义事件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36156465/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Listen to custom event in Vue.js
提问by vbarbarosh
Vue.js works great with browser events such as click
or mousedown
. But not work at all with custom events. Here is the code:
Vue.js 可以很好地处理浏览器事件,例如click
或mousedown
。但根本不适用于自定义事件。这是代码:
HTML:
HTML:
<div id="app" style="display: none" v-show="true">
<div v-el:ping v-on:ping="ping">
<div>
<button v-on:click="click">Click</button>
</div>
</div>
</div>
JavaScript:
JavaScript:
new Vue({
el: '#app',
data: {
},
methods: {
ping: function (event) {
console.log('Vue ping', event);
alert('Vue ping');
},
click: function (event) {
jQuery(event.target).trigger('ping');
}
},
ready: function () {
console.log(this.$els);
jQuery(this.$els.ping).on('ping', function (event) {
console.log('jQuery ping', event);
alert('jQuery ping');
});
}
});
I expect alert with Vue ping
and jQuery ping
. But only the later pops up.
我期待着与警报Vue ping
和jQuery ping
。但只有后者弹出。
回答by Linus Borg
Vue has it's own internal system for custom events, which you should use instead of jQuery / native DOM events:
Vue 有它自己的自定义事件内部系统,你应该使用它来代替 jQuery/原生 DOM 事件:
click: function (event) {
// jQuery(event.target).trigger('ping');
this.$dispatch('ping', event.target) // send event up the parent chain, optionally send along a reference to the element.
// or:
this.$emit('ping') // trigger event on the current instance
}
Edit: $dispatch is for parent-child communication, You seem to want to trigger a custom event from within the same comonent. In that case, you could instead simply call a method.
编辑: $dispatch 用于父子通信,您似乎想从同一个组件内触发自定义事件。在这种情况下,您可以改为简单地调用一个方法。
If you still want to listen to a custom event inside the same component, you:
如果您仍想侦听同一组件内的自定义事件,您可以:
- want use $emit
cannnot use
v-on:custom-event-name
in the template (that's only to be used on components). Rather, add the event method to theevents:
:events: { ping: function() {....} }
- 想要使用 $emit
不能
v-on:custom-event-name
在模板中使用(只能在组件上使用)。相反,将事件方法添加到events:
:事件:{平:函数(){....}}
回答by Panama Prophet
You should avoid to mix a dom events and vue-components related ones because it's a different layers of abstraction.
你应该避免混合 dom 事件和 vue-components 相关的事件,因为它是不同的抽象层。
Anyway, if you still want to do that, I think you need to cache this.el inside a vue-component instance or take it via computed-property like this
无论如何,如果您仍然想这样做,我认为您需要将 this.el 缓存在 vue-component 实例中,或者像这样通过计算属性获取它
{
computed : {
jqueryEl(){ return $(this.el) }
}
}
And then trigger a custom jQuery events by this.jqueryEl.trigger('ping')
.
然后触发自定义 jQuery 事件this.jqueryEl.trigger('ping')
。
Sure to properly take care of keep the element's bindings up to date! For example you can bind jQuery events dynamically (and also unbind on component destroy!) like this:
确保正确处理保持元素的绑定是最新的!例如,您可以像这样动态绑定 jQuery 事件(也可以在组件销毁时解除绑定!):
ready : function(){
jQuery('body').on('ping.namespace', '[data-jquery="ping"]', function(){ ... })
},
destroy : function(){
jQuery('body').off('ping.namespace')
}
And don't forget to add attribute [data-jquery="ping"]
to an element which you would like to response a ping event.
并且不要忘记将属性添加[data-jquery="ping"]
到您想要响应 ping 事件的元素。
Hope this information helps you to achieve the expected result.
希望这些信息可以帮助您达到预期的结果。
回答by Jeff
Here it is in vanilla JS:
这是香草JS:
HTML:
HTML:
<div id="app">
<div v-el:ping>
<div>
<button v-on:click="click">Click</button>
</div>
</div>
</div>
JS:
JS:
(function() {
new Vue({
el: '#app',
data: {
event: null
},
methods: {
ping: function(event) {
alert('Vue ping');
},
click: function(event) {
this.$els.ping.dispatchEvent(this.event);
}
},
ready: function() {
this.event = document.createEvent("HTMLEvents");
this.event.initEvent("ping", true, true);
this.$els.ping.addEventListener('ping', this.ping);
}
});
})();