简体   繁体   English

在Vue.js中收听自定义事件

[英]Listen to custom event in Vue.js

Vue.js works great with browser events such as click or mousedown . Vue.js适用于浏览器事件,例如clickmousedown But not work at all with custom events. 但是根本不适用于自定义事件。 Here is the code: 这是代码:

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 . 我希望通过Vue pingjQuery ping提醒。 But only the later pops up. 但只有后来弹出。

CodePen CodePen

Vue has it's own internal system for custom events , which you should use instead of jQuery / native DOM events: Vue拥有自己的自定义事件内部系统 ,您应该使用它而不是jQuery / native 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. 编辑:$ dispatch用于父子通信,您似乎想要从同一个组件中触发自定义事件。 In that case, you could instead simply call a method. 在这种情况下,您可以简单地调用方法。

If you still want to listen to a custom event inside the same component, you: 如果您仍想在同一组件中收听自定义事件,则:

  1. want use $emit 想要使用$ emit
  2. cannnot use v-on:custom-event-name in the template (that's only to be used on components). 不能使用v-on:custom-event-name模板中的v-on:custom-event-name (仅用于组件)。 Rather, add the event method to the events: : 而是将事件方法添加到events:

    events: { ping: function() {....} } 事件:{ping:function(){....}}

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

})();

pen: http://codepen.io/anon/pen/wGdvaV?editors=1010#0 笔: http//codepen.io/anon/pen/wGdvaV?编辑= 010#0

You should avoid to mix a dom events and vue-components related ones because it's a different layers of abstraction. 你应该避免混合dom事件和vue组件相关的事件,因为它是一个不同的抽象层。

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 无论如何,如果你仍然想这样做,我认为你需要在vue组件实例中缓存this.el或者通过如下的computed-property获取它

{
    computed : {
        jqueryEl(){ return $(this.el) }
    }
}

And then trigger a custom jQuery events by this.jqueryEl.trigger('ping') . 然后通过this.jqueryEl.trigger('ping')触发自定义jQuery事件。

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. 希望这些信息可以帮助您实现预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM