8

$emitカスタム ディレクティブからのイベントが必要です。出来ますか?

ディレクティブ.js:

vnode.context.$emit("myEvent") // nothing append
vnode.child.$emit("myEvent")   // error
vnode.parent.$emit("myEvent")  // error

component.vue:

<div v-directive.modifier="binding" @myEvent="method()"></div>

それが可能かどうか、または何かトリックがあるかどうか知っていますか?

ありがとう

4

1 に答える 1

14

A<div>は ではありVueComponentません。つまり、$emitメソッドがありません。

したがって、Vue カスタム ディレクティブがイベントを発行するようにするには、最初にいくつかのチェックを行う必要があります。

  • ディレクティブが Vue カスタム コンポーネントで使用された場合、そのコンポーネントのインスタンスの呼び出し$emit()
  • ディレクティブが通常の DOM 要素で使用された場合(... がないため$emit()) 、.を使用してネイティブ DOM イベントをディスパッチ.dispatchEventします。

幸いなことに、Vue のv-onリスナーはネイティブのカスタム イベントに応答します。

それだけです。以下デモ実装。

Vue.component('my-comp', {
  template: `<input value="click me and check the console" size="40">`
});

Vue.directive('my-directive', {
  bind: function (el, binding, vnode) {

    // say you want to execute your logic when the element is clicked
    el.addEventListener('click', function (e) {
    
      var eventName = 'my-event';
      var eventData = {myData: 'stuff - ' + binding.expression}
      if (vnode.componentInstance) {
      	vnode.componentInstance.$emit(eventName, {detail: eventData}); // use {detail:} to be uniform
      } else {
      	vnode.elm.dispatchEvent(new CustomEvent(eventName, {detail: eventData}));
      }

    })
  }
})

new Vue({
  el: '#app',
  methods: {
    handleStuff(e) { console.log('my-event received', e.detail); }
  }
})
<script src="https://unpkg.com/vue@2.5.15/dist/vue.min.js"></script>

<div id="app">
  <div v-my-directive.modifier="'native element'" @my-event="handleStuff">CLICK ME AND CHECK THE CONSOLE</div>
  <hr>
  <my-comp v-my-directive.modifier="'custom component'" @my-event="handleStuff"></my-comp>
</div>

于 2018-03-13T21:27:52.033 に答える