【发布时间】:2020-06-18 14:39:45
【问题描述】:
让我们看下面的场景,其中WelcomePage(父)使用LoginForm(子)和自定义事件@submit:
// WelcomePage.vue
<LoginForm @submit="handleLogin">Login<Button>
那么,组件LoginForm的代码如下:
// LoginForm
<form @submit.prevent="handleSubmit"> ... </form>
handleSubmit() {
// do some stuff...
// following Vue docs to create custom events.
this.$emit('submit', 'some_data')
// OR... we can also use $listeners.
this.$listeners.submit('some_data')
// do other stuf...
}
使用this.$listeners.submit() 代替this.$emit('submit') 有什么弊端吗?
使用this.$listeners 的一个优点是它可以与await 一起使用,is a limitation of $emit 迫使我们使用done() 回调方法。当我们想在自定义事件完成后更新某些状态(this.isLoading)时,它很有用。
将 $emit 与回调一起使用:
// LoginForm.vue
async handleSubmit() {
this.isLoading = true
this.$emit('submit', 'some_data', () => {
this.isLoading = false
})
}
// WelcomePage.vue
async handleLogin(data, done) {
// await for stuff related to "data"...
done();
}
将 $listener 与 await 一起使用:
// LoginForm.vue
async handleSubmit() {
this.isLoading = true
await this.$listeners.submit('some_data') // no need to use done callback
this.isLoading = false
}
所以,我的问题是:可以使用this.$listeners 吗? this.$emit 的目的/优势是什么?
更新:
将 prop isLoading 从父级传递给子级将是第一个(明显的)选项,而不是使用 $emit。
但这需要在每次我们使用子组件时在handleSubmit 上设置和更新this.isLoading = true | false(并且它被大量使用)。所以我正在寻找一种解决方案,当调用@submit 时,父母不需要担心isLoading。
【问题讨论】:
-
只是出于好奇.. 为什么要异步发射?
-
@SølveTornøe 一个具体的例子:
LoginForm需要显示“加载状态”,而WelcomePage正在处理提交(异步)。完成后,LoginForm需要清理加载状态。 -
我认为在这种情况下通常的“goto”将是一个额外的发射
loading。然后你在 async 函数之前发出 loading=true ,在之后发出 loading=false 。 -
我误解了你的回答。您实际上想要做的是向
LoginForm提供加载道具。一旦父级获得了发射some_data,它会将加载设置为true,一旦完成就会返回false。
标签: javascript vue.js