【问题标题】:Vue async / await with $emitVue async / await 与 $emit
【发布时间】:2021-03-11 23:36:27
【问题描述】:

我有一个对话框组件,它在提交时执行两个异步函数。我的目标是保持对话框打开并显示加载状态,直到两个功能都完成。之后,我想关闭对话框。

我在父组件中定义的提交函数如下所示:

 async submit() {
    await this.foo1();
    await this.foo2();
}

这个函数作为一个 prop 传递给对话框组件:

<app-dialog @submit="submit" />

在我的对话框组件中,单击按钮时,我尝试这样做:

async onClick() {
    await this.$emit('submit');
    this.closeDialog();
},

但是,对话框会立即关闭,而不是等待执行提交。完成此任务的最佳方法是什么?

【问题讨论】:

  • this.$emit 是否返回一个可以等待的 promise/thenable?如果不是,我会假设 await 什么都不做
  • @evolutionxbox 很遗憾没有,我在尝试时得到了"TypeError: _this.$emit(...).then is not a function"
  • _this.$emit(...).then 这看起来您的转译器正在用 then 替换 await 语法?
  • Nono,当我尝试做 this.$emit('submit').then(() =&gt; // code) 时我明白了

标签: javascript vue.js async-await


【解决方案1】:

我设法通过在对话框组件中传递回调来找到解决方案:

submit() {
    this.$emit('submit', () => this.closeDialog())
},

然后在我的父组件中调用该回调:

async submit(closeDialog) {
    await this.foo1();
    await this.foo2();
    closeDialog()
}

但一定有比这更好的解决方案!

【讨论】:

  • 我认为这是一个优雅的解决方案!
  • 没有比 async/await 更优雅的了!
  • 我真的很喜欢这个,因为你可以在发射时同时传递你的参数,stackoverflow.com/a/66585473/6434747 使得传递任何参数变得困难,因为它只会执行函数
  • 几个月后回来,我想再次投票给这个。
【解决方案2】:

对于这类问题还有另一种模式,即将回调函数作为道具传递。

在您的对话框组件上:

props: {
  onSubmit: {
    type: Function,
    required: true // this is up to you
},

[...]

// in your methods
async onClick() {
  if (this.onSubmit && typeof this.onSubmit === 'function') {
    await this.onSubmit();
  }
  this.closeDialog();
}

然后,在你的父组件中:

<app-dialog :on-submit="submit" />

[...]

// in your methods:

async submit() {
  await this.foo1();
  await this.foo2()
}

请记住一些事情

  1. 在哪里处理你的承诺很重要。例如,如果您想在出现错误时保持 modal 处于打开状态,您可以在 modal 组件中进行错误处理,或者至少将一些错误转发给它。

  2. 值得进一步探索函数的验证,例如检查它是否真的返回了一个承诺,然后等待它,否则做其他事情。

  3. 即使只是一点点,这种模式也会给你的解决方案增加一点耦合,所以你不想用回调函数替换所有事件!

【讨论】:

  • 这会起作用,但是将函数作为道具传递是 Vue 中的反模式。
  • 我很同意你@Coelacanth 的观点,在大多数情况下传递回调是一个坏主意。我仍然会证明这种情况不是那些“大多数情况”之一。大型库将实现此模式以向其组件添加防护和挂钩。请参阅elementui.github.io/dev/master/#/en-US/component/dialog before-close 道具。
猜你喜欢
  • 2018-10-18
  • 2021-11-13
  • 1970-01-01
  • 2021-06-15
  • 1970-01-01
  • 2019-09-06
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
相关资源
最近更新 更多