【问题标题】:VueJS Custom directive + emit eventVueJS 自定义指令 + 发射事件
【发布时间】:2018-08-22 04:43:00
【问题描述】:

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

directive.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>

你知道这是否可能或有什么技巧吗?

谢谢

【问题讨论】:

  • 你想什么时候触发事件?
  • 我在一个组件(component.vue)中监听。组件在页面中。组件有指令(directive.js)。

标签: vue.js vuejs2 vue-directives


【解决方案1】:

&lt;div&gt; 不是VueComponent,这意味着它没有$emit 方法。

所以要让你的 Vue 自定义指令发出一个事件,你必须先做一些检查:

  • 如果该指令用于 Vue 自定义组件,则调用该组件实例的$emit()
  • 如果该指令用于常规 DOM 元素(...因为没有 $emit()...),则 调度原生 DOM 事件使用 @ 987654321@.

幸运的是,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>

【讨论】:

  • 谢谢。但它在哪里写? vuejs.org/v2/api/#vm-emitvuejs.org/v2/guide/custom-directive.html。另外,我是否需要在使用此指令的 div 或组件中停止传播,并阻止或停止?
  • “写在哪里”是什么意思?上面有一个演示。无需停止传播,除非您有专门的要求。如果你不知道那是因为你没有它。
  • 对不起,英语不好:D。我没有在文档中看到有关“vnode.componentInstance”或您向我描述的机制的任何内容。您的演示非常好,谢谢。
  • 啊,是的,componentInstance 在界面中被“记录”:github.com/vuejs/vue/blob/dev/flow/vnode.js#L14 它是其中的一部分。它不是内部属性,因为内部属性以_ 开头(并且不出现在界面中)。和大家熟知的vnode.context一样,估计用的教程不多,因为它是Vue的高级特性。
  • 嗯,好的。再次感谢。您知道我在哪里可以找到有关高级功能的信息吗?我需要vuex,多用户实时共享商店...而且,我刚刚在这里发布了一个关于vuex的问题:stackoverflow.com/questions/49280576/vuejs-vuex-mapactions
猜你喜欢
  • 2016-04-04
  • 2020-02-17
  • 2016-04-29
  • 2023-03-07
  • 1970-01-01
  • 2021-09-26
  • 2019-10-01
  • 2017-10-19
  • 2023-04-04
相关资源
最近更新 更多