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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 18:42:47  来源:igfitidea点击:

Listen to custom event in Vue.js

javascriptvue.js

提问by vbarbarosh

Vue.js works great with browser events such as clickor mousedown. But not work at all with custom events. Here is the code:

Vue.js 可以很好地处理浏览器事件,例如clickmousedown。但根本不适用于自定义事件。这是代码:

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 pingand jQuery ping. But only the later pops up.

我期待着与警报Vue pingjQuery ping。但只有后者弹出。

CodePen

代码笔

回答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:

如果您仍想侦听同一组件内的自定义事件,您可以:

  1. want use $emit
  2. cannnot use v-on:custom-event-namein the template (that's only to be used on components). Rather, add the event method to the events::

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

  1. 想要使用 $emit
  2. 不能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);
    }
  });

})();

pen: http://codepen.io/anon/pen/wGdvaV?editors=1010#0

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