Vue.js - Emit event from directive

后端 未结 7 463
北海茫月
北海茫月 2021-02-02 12:37

Is it possible to emit a custom event from the directive in the component to which this directive is attached.

I was expecting it to work as described

7条回答
  •  被撕碎了的回忆
    2021-02-02 13:30

    The above answers are great but some of them are out-of-date. Here's the way I solve the problem by integrating them into a workable POC.

    // src/directives/ClickOutside.js
    export default {
      stopProp(e) {
        e.stopPropagation();
      },
      bind(el, binding, vnode) {
        el._clickOutside = e => {
          vnode.context.$emit(binding.expression, e);
        };
        el.addEventListener('click', binding.def.stopProp);
        document.body.addEventListener('click', el._clickOutside);
      },
      unbind() {
        if (!el._clickOutside) {
          return;
        }
        el.removeEventListener('click', binding.def.stopProp);
        document.body.removeEventListener('click', el._clickOutside);
        delete el._clickOutside;
      }
    };
    
    // src/directives/index.js
    import Vue from 'vue';
    import ClickOutside from './ClickOutside';
    
    Vue.directive('ClickOutside', ClickOutside);
    

    Import the directives in main.js:

    // src/main.js
    import './directives';
    

    Use the directive with listening to the event emission in a Vue component:

    // src/components/Component.vue
    
    
    
    

    Basically, in vnode.context.$emit, the binding.expression is the string (i.e., "hideElement" in this example) you declared in the v-close-outside. To retrieve the emission from the directive, use this.$on('hideElement') to listen to it.

提交回复
热议问题