VueJS自定义指令+发射事件

Bri*_*eau 6 vue.js vuejs2 vuejs-directive

我需要$emit来自自定义指令的事件。可能吗?

指令.js:

vnode.context.$emit("myEvent") // nothing append
vnode.child.$emit("myEvent")   // error
vnode.parent.$emit("myEvent")  // error
Run Code Online (Sandbox Code Playgroud)

component.vue:

<div v-directive.modifier="binding" @myEvent="method()"></div>
Run Code Online (Sandbox Code Playgroud)

您知道是否有可能或有任何技巧?

谢谢

acd*_*ior 8

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); }
  }
})
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)