javascript - Vue.js - 从指令发出事件

标签 javascript vue.js vue-component

是否有可能指令该指令附加到的组件中发出自定义事件。

我原以为它会像示例中描述的那样工作,但事实并非如此。

例子:

//Basic Directive
<script>
  Vue.directive('foo', {
    bind(el, binding, vnode) {
      setTimeout(() => {
        //vnode.context.$emit('bar'); <- this will trigger in parent
        vnode.$emit('bar');
      }, 3000);
    }
  });
</script>


//Basic Component
<template>
  <button v-foo @bar="change">{{label}}</button>
</template>
<script>
  export default{
    data() {
      return {
        label: 'i dont work'
      }
    },
    methods: {
      change() {
        this.label = 'I DO WORK!';
      }
    }
  }
</script>

对此事有什么想法吗?我错过了什么吗?

JSFiddle:https://jsfiddle.net/0aum3osq/4/

更新 1:

好吧,我发现如果我在指令它将触发 bar 事件处理程序。

更新 2:

临时解决方案:

  /*temp. solution*/
  var emit = (vnode, name, data) => {
    var handlers = vnode.data.on;

    if (handlers && handlers.hasOwnProperty(name)) {
      var handler = handlers[name];
      var fn = handler.fns || handler.fn;

      if (typeof fn === 'function') {
        fn(data);
      }
    }
  } 

//Basic Directive
<script>
  Vue.directive('foo', {
    bind(el, binding, vnode) {
      setTimeout(() => {
        emit(vnode, 'bar');
      }, 3000);
    }
  });
</script>

最佳答案

所以我在 Vue 2+ 中使用的解决方案(考虑到目前还没有答案):

在指令中添加方法:

var emit = (vnode, name, data) => {
  var handlers = (vnode.data && vnode.data.on) ||
    (vnode.componentOptions && vnode.componentOptions.listeners);

  if (handlers && handlers[name]) {
    handlers[name].fns(data);
  }
}

这样调用它:

bind(el, binding, vnode) {
  emit(vnode, 'bar' , {some: 'event', data: 'here'});
}

方法的好处:

1 在您的项目中保持相同的代码风格,这意味着每个处理程序都可以声明为
v-on:handler_name 并以有意义的(对于开发人员)方式进行处理。如果不深入研究文档/代码,其他解决方案(例如将回调作为参数发送)有时会令人困惑且不明显。

2 使用内置事件系统还可以优雅地处理事件对象。例如,这段代码可以很好地工作:

<button v-foo @bar="bar(1, $event, 2)">{{label}}</button>
...
methods: {
  bar(one, event, two) { console.log(one, event, two); }
} 

编辑:

在 v2.1+ 中你可以使用这个内部指令绑定(bind):

vnode.context.$emit(eventname)

关于javascript - Vue.js - 从指令发出事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40655333/

相关文章:

javascript - Extjs 将事件添加到 Controller 中网格形式的按钮

javascript - Papaparse 对奇怪字符的正确编码

javascript - JS加密-python解密

javascript - 如何在 Chrome 插件/其他来源中使用 CSRF token

javascript - 在 Docker 中运行 nuxt js 应用程序

javascript - 每次任何变量发生变化时,VueJS 中的列表都会重新渲染,即使是不相关的

vue.js - Vue - 深入观察对象数组的变化,无论是添加对象还是修改对象

javascript - Jest 单元测试 - SyntaxError : Cannot use import statement outside a module

javascript - 添加变量以触发父级中的函数 - Vue

vue.js - Vue组件中删除后不重新加载页面