Open garyo opened 5 years ago
Hey @garyo sorry for the late response, I've been swamped lately. I think this is a great idea. I might be able to tackle this in a bit unless you want to shoot a PR over?
I'm not enough of a Vue expert yet to try that :-)
I've been working on this this morning. Figured I'd share the proposed API. We'll expose a boundary
slot scope. On that slot scope there will be three properties:
hasError
- (boolean) whether there was an error captured or noterr
- (Error) the error itselfinfo
- (string) string containing information on where the error was capturedExample usage:
<error-boundary #boundary="{ hasError }">
<div v-if="!hasError">No error occurred.</div>
<div v-else>Message to appear if error occurred.</div>
</error-boundary>
That looks OK to me. Alternatively (or also?) you could have a named "error" slot as well as the default slot for the content to wrap:
<error-boundary #boundary="{ hasError, errmsg}">
<ImUnstable/>
<MoreContent/>
<div slot="error" class="error">An error occurred: {{ errmsg }}</div>
</error-boundary>
That way users don't have to fiddle with v-if/v-else.
I think the above might not compile.
<div v-slot:error>
wouldn't work because slots only work on <template>
or components. Furthermore, using the slot-scope on the parent <error-boundary>
would throw the error:
To avoid scope ambiguity, the default slot should also use <template> syntax when there are other named slots.
Which, if I'm not mistaken, you'd have to end up doing something like:
<error-boundary>
<template #boundary="{ hasError, ... }">
Has access to hasError/err/info.
</template>
<template v-slot:error>
Default fallback content. Has no access to error boundary state.
</template>
</error-boundary>
I could be wrong since I haven't kept up with Vue these past few months 😅
I'll probably go ahead and push the above live while I look into just the slot
option.
You're right -- you have to use a <template>
for the error message unless it's already a component. And I see your point about where to put the slot props -- I'm still learning all this stuff!
Clearly the default slot doesn't normally need any access to the error slot props.
So perhaps the "normal" use would be something like this:
<error-boundary>
<ImUnstable/>
<MoreContent/>
<template v-slot:boundary="{errmsg}">
<div class="error">An error occurred: {{ errmsg }}</div>
</template>
</error-boundary>
Is that sort of like what you meant? That looks nice and usable to me. Though maybe it's better to name the scope "error", like v-slot:error="{errmsg"}
?
This is a really nice component, thanks! It would be nice not to have to create a whole component just for a bit of fallback text/html. Is it possible to just have a slot for the fallback?