feat(runtime-core): return result of handlers in emit#6819
feat(runtime-core): return result of handlers in emit#6819jaulz wants to merge 4 commits intovuejs:mainfrom
emit#6819Conversation
sxzz
left a comment
There was a problem hiding this comment.
I'm not sure if we should have an issue discussing this feature first.
| } | ||
| instance.emitted[handlerName] = true | ||
| callWithAsyncErrorHandling( | ||
| result = callWithAsyncErrorHandling( |
There was a problem hiding this comment.
If handler and onceHandler are existing at the same time, the result will be overwritten.
| return compatInstanceEmit(instance, event, args) | ||
| } | ||
|
|
||
| return result |
There was a problem hiding this comment.
Should change type declaration too
core/packages/runtime-core/src/componentEmits.ts
Lines 57 to 70 in 45782df
Yep, for sure, I thought this PR could serve as an initial base to discuss it further. Happy to move it somewhere else if you want? |
❌ Deploy Preview for vuejs-coverage failed.
|
| instance.emitted = {} as Record<any, boolean> | ||
| } else if (instance.emitted[handlerName]) { | ||
| return | ||
| } else if (!instance.emitted[handlerName]) { |
There was a problem hiding this comment.
If !instance.emitted is true, it will skip else.
| } else if (!instance.emitted[handlerName]) { | |
| } if (!instance.emitted[handlerName]) { |
| const results = [] | ||
| if (handler) { | ||
| callWithAsyncErrorHandling( | ||
| const values = callWithAsyncErrorHandling( |
There was a problem hiding this comment.
I wonder if values could be an array? If handler is not an array, then values is not.
There was a problem hiding this comment.
Based on the definition of callWithAsyncErrorHandling it can return an array:
core/packages/runtime-core/src/errorHandling.ts
Lines 77 to 98 in ae4b078
There was a problem hiding this comment.
It depends on handler. If handler is a function, then callWithAsyncErrorHandling will return the result directly. I don't think handler will be an array.
|
It's an underrated feature here! <!-- Outside -->
<SomeFormComponent
@validate="validateData"
@submit="saveDataToDatabase"
/>
<script>
async function validateData() {
await API.validateXXX()
}
async function saveDataToDatabase() {
await API.postXXX()
}
</script><!-- Inside -->
<form />
<script>
const emit = defineEmits()
async function handleClickSubmit() {
startLoading()
await emit('validate', data)
await emit('submit', data)
stopLoading()
}
</script>Nice and clean, right? defineEmits<{
(e: 'submit'): Promise<undefined> // ❌
(e: 'submit'): void // ✅
}>()The return type can only be void. defineEmits<{
(e: 'aaa'): void
(e: 'bbb'): void
/** .... */
}>() |
|
I realy need this feature, is this feature likely to be merged? when will it be available? |
|
There's an RFC discussion at vuejs/rfcs#587 that proposes a slightly different way of approaching this. I'm not sure which I prefer. Just to clarify, a single event can have multiple listeners. In the Playground below, the emitted event triggers 3 handlers.
|
|
I prefer the proposal in this PR to vuejs/rfcs#587. This implementation is more flexible, giving the user control over exactly what is returned, rather than just returning a boolean value. |
It would be great if
emitcould return the result of the handlers. A typical example could be to show a loading indicator while asynchronous event handlers are running:This is just a basic example that does not consider errors or multiple clicks but it gives an idea what would be possible. The same could already be implemented with props but it duplicates the handling.
If you think this is a good idea, I can extend the PR with corresponding tests.