2016-03-22 32 views
5

Vue.js świetnie współpracuje z wydarzeniami przeglądarkowymi, takimi jak click lub mousedown. Ale nie działa w ogóle z niestandardowymi zdarzeniami. Oto kod:Słuchaj niestandardowych wydarzeń w Vue.js

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:

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

Spodziewam alert z Vue ping i jQuery ping. Ale tylko później wyskakuje.

CodePen

+0

gdzie jest problem z kodem? – Gintoki

+0

@John '' ping'' (gdzie '' alert ('Vue ping') '') nie jest wywoływany – vbarbarosh

Odpowiedz

1

Oto ona w waniliowym JS:

HTML:

<div id="app"> 
    <div v-el:ping> 
    <div> 
     <button v-on:click="click">Click</button> 
    </div> 
    </div> 
</div> 

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

})(); 

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

+0

To jest bez znaczenia. Używam 'jQuery (event.target) .trigger ('ping')' ', ponieważ nie wiem, kto będzie obsługiwał to wydarzenie. Muszę poinformować rodzica, że ​​coś się stało z jego potomkiem. – vbarbarosh

+0

Czy spojrzałeś na '$ dispatch'? http://vuejs.org/api/#vm-dispatch – Jeff

+0

Tak. http://stackoverflow.com/questions/36156465/listen-to-custom-event-in-vue-js/36159698#comment59980051_36159698 – vbarbarosh

6

Vue ma swój własny wewnętrzny system for custom events, który należy użyć zamiast jQuery/rodzimych zdarzeń 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 
} 

Edycja: $ wysyłka jest do komunikacji rodzic-dziecko, wydają się chce wyzwalać zdarzenia niestandardowego w obrębie tej samej comonent. W takim przypadku możesz po prostu wywołać metodę.

Jeśli nadal chcą słuchać niestandardowego zdarzenia wewnątrz tego samego komponentu, należy:

  1. chcesz użyć $ emitują
  2. cannnot używać v-on:custom-event-name w szablonie (to tylko do stosowania na elementach) . Raczej dodać metodę zdarzeń do events::

    zdarzeń: { ping: function() {....} }

+0

To nie działa. "Ten system zdarzeń jest niezależny od macierzystych zdarzeń DOM i działa inaczej." Myślę, że jest to komunikacja między komponentami Vue, a nie między węzłami DOM. – vbarbarosh

+0

To nie działa w jaki sposób? Od kiedy korzystasz z Vue.js, miałem wrażenie, że chciałbyś przekazać beweteen komponenty? ' Dlaczego chciałbyś się komunikować pomiędzy węzłami DOM w Vue - ponieważ celem Vue jest oddzielenie logiki biznesowej od DOM? Może pomożemy Ci przetłumaczyć Twój przypadek na "sposób Vue", jeśli podasz dodatkowe informacje na jego temat. –

+0

Byłbym bardzo wdzięczny, jeśli poprawisz podany kod źródłowy. Pytanie brzmiało: jak dołączyć niestandardową procedurę obsługi zdarzeń do Vue, aby mogła przechwytywać zdarzenia emitowane przez jQuery.trigger. – vbarbarosh

1

nie należy mieszać zdarzeń DOM i vue-komponenty powiązane, ponieważ są to różne warstwy abstrakcji.

W każdym razie, jeśli nadal chcesz to zrobić, myślę, że trzeba buforować this.el wewnątrz instancji vue-komponent lub wziąć go za pomocą komputerowej-PROPERTY jak ten

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

A potem wywołać zwyczaj Zdarzenia jQuery: this.jqueryEl.trigger('ping').

Oczywiście, aby dbać o zachowanie aktualności wiązania elementu! Na przykład można powiązać zdarzenia jQuery dynamicznie (a także rozpiąć na składniku zniszczyć!) Tak:

ready : function(){ 
    jQuery('body').on('ping.namespace', '[data-jquery="ping"]', function(){ ... }) 
}, 
destroy : function(){ 
     jQuery('body').off('ping.namespace') 
} 

I nie zapomnij dodać atrybut [data-jquery="ping"] do elementu, który chcieliby Państwo odpowiedzi na zdarzenie ping.

Mam nadzieję, że te informacje pomogą Ci osiągnąć oczekiwany rezultat.