是否可以将$ emit作为同步模式执行并从发出事件获取结果

时间:2019-03-26 18:36:58

标签: javascript vue.js vuejs2 emit

是否有可能以同步方式发出并以调用方法本身的形式返回结果。因此,我想在$ emit完成之后执行下一条语句。其如下:

Parent component has method, 
                 doCustomValidation();

child component is as follow:
methods:
{
  Save: function(){
 // Can I get the response here from parent component and then, execute 
    doGenericValidation ?

 var errorFields = this.$emit('custom-validation');  
   doGenericValidation(errorFields);   //this is generic validations
}

3 个答案:

答案 0 :(得分:2)

您不应尝试使其同步。相反,您可能可以使用以下想法:

methods: {
    myMethod() {
        // Pass a function as a parameter.
        this.$emit('custom-validation', this.onComplete);
    },
    onComplete() {
        // Do stuff after custom-validation has completed.
    }
}

然后在使用事件的任何组件中:

<some-component @custom-validation="doStuff" />
<script>
...
methods: {
    doStuff(done) {
        // Your logic here. After that, call the callback function.
        done();
    }
}
...

答案 1 :(得分:1)

不。 $emit将始终排队。可能还会有多个侦听器,因此返回值实际上没有任何意义。

作为一种解决方法,您可以将函数作为属性发送,然后直接调用它。

答案 2 :(得分:1)

您可以为promise创建一个基于promise的包装,并等待其结果。

这是我为项目创建的一个非常通用的解决方案:

    async emitPromised(method, ...params){
        let listener = this.$listeners[method] || this.$attrs[method] || this[method]
        if(listener){
            let res = await listener(...params)
            return res === undefined || res
        }
        return false
    },

现在您可以像这样使用它:

        async onDelete(){
            this.isDeleting = true
            let res = await this.emitPromised("delete")
            this.isDeleting = false
            if(res){
                this.closeConfirm()
            }
        },

您可以通过mixin包含此方法,也可以将其全局附加到Vue实例,以便所有组件均可使用。

请注意,$listeners使用@v-on(例如<MyComponet @click="onClick"/>)存储绑定到该组件的所有方法,而$attrs存储传递给使用v-bind:(例如<MyComponet :click="onClick"/>)的组件