Слушайте пользовательское событие в Vue.js

Vue.js прекрасно работает с событиями браузера, такими как click или же mousedown, Но не работать вообще с пользовательскими событиями. Вот код:

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

Я ожидаю тревоги с Vue ping а также jQuery ping, Но только позже всплывает.

CodePen

4 ответа

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
}

Редактировать: $dispatch для связи родитель-потомок. Вы, кажется, хотите инициировать пользовательское событие из того же компонента. В этом случае вы могли бы просто вызвать метод.

Если вы все еще хотите прослушать пользовательское событие внутри того же компонента, вы:

  1. хочу использовать $emit
  2. не может использовать v-on:custom-event-name в шаблоне (это только для компонентов). Скорее, добавьте метод события к events::

    события: { ping: function() {....} }

Вы должны избегать смешивания dom-событий и vue-компонентов, связанных, потому что это разные уровни абстракции.

В любом случае, если вы все еще хотите это сделать, я думаю, вам нужно кэшировать this.el внутри экземпляра vue-component или взять его через свойство computed-property, например

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

И затем вызвать пользовательские события JQuery по this.jqueryEl.trigger('ping'),

Обязательно позаботьтесь о своевременном обновлении привязок элемента! Например, вы можете динамически связывать события jQuery (а также отменять привязку при уничтожении компонента!) Следующим образом:

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

И не забудьте добавить атрибут [data-jquery="ping"] к элементу, который вы хотели бы ответить на событие ping.

Надеюсь, что эта информация поможет вам достичь ожидаемого результата.

Вот это в ванильном 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);
    }
  });

})();

ручка: http://codepen.io/anon/pen/wGdvaV?editors=1010

Я столкнулся с той же проблемой, и решение довольно простое, если вы используете v-autocomplete из Vuetify.

Что я сделал

  1. Добавьте ключ в данные, я называю этоsearchText
  2. Свяжите это свойство сv-model:search
  3. Добавьте обработчик событий под названием@update:modelValue
  4. Объявите метод и добавьте этот метод в@update:modelValue="emptySearchText"

Вот пример.

      <v-autocomplete
  label="Your Label"
  :items="items"
  v-model="selected"
  v-model:search="searchText"
  @update:modelValue="emptySearchText"
  multiple>
</v-autocomplete>

      data: () => ({
  searchText: null
})


methods: {
  emptySearchText () {
    this.searchText = '';
  }
}

Проверьте это для получения дополнительной информации.https://vuetifyjs.com/en/api/v-autocomplete/#events-update:modelValue

Другие вопросы по тегам