Appearance
BizErrorBoundary 错误边界
捕获子树渲染期异常(onErrorCaptured 并阻断向上传播),用兜底视图替换崩溃区域,防止整页白屏;支持一键重试(清空错误重渲染子树)、fallback 插槽完全自定义兜底视图、error 事件接入监控上报。平台级稳定性兜底、第三方/试验性模块隔离。
基础兜底
这段文案在边界之外,永远不会被波及。
子组件 setup 抛错 → 兜底视图;边界外内容不受影响。
<script setup lang="ts">
/** 场景:模块崩溃兜底——子组件渲染抛错时展示兜底视图,页面其余部分不受影响 */
import { defineComponent, ref } from 'vue'
import { ElButton, ElMessage } from 'element-plus'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
// 模拟会崩的第三方卡片(render 期间抛错,由错误边界捕获)
const BrokenWidget = defineComponent({
name: 'BrokenWidget',
render() {
throw new Error('模拟渲染异常:上游返回的数据格式不符合预期')
},
})
const mountBroken = ref(true)
</script>
<template>
<div style="max-width: 560px">
<p style="margin-bottom: 10px; font-size: 13px; color: var(--el-text-color-secondary)">
这段文案在边界之外,永远不会被波及。
</p>
<BizErrorBoundary>
<BrokenWidget v-if="mountBroken" />
<ElAlert v-else type="success" :closable="false" show-icon title="正常内容区域" />
</BizErrorBoundary>
<div style="margin-top: 12px">
<ElButton size="small" @click="mountBroken = !mountBroken; ElMessage.info('切换子内容')">
切换子内容
</ElButton>
</div>
</div>
</template>
显示代码
重试恢复
模拟远程配置加载完成
先打开开关,再点兜底视图里的「重试」数据就绪前抛错,打开开关后点「重试」正常渲染。
<script setup lang="ts">
/** 场景:重试恢复——数据就绪前抛错,兜底视图点「重试」后正常渲染 */
import { defineComponent, h, ref } from 'vue'
import { ElSwitch, ElTag } from 'element-plus'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
const ready = ref(false)
// 模拟依赖远程数据的模块:数据未就绪时渲染抛错
const RemoteWidget = defineComponent({
name: 'RemoteWidget',
setup() {
if (!ready.value) throw new Error('配置尚未加载完成')
return () => h('div', { style: 'padding: 20px; text-align: center' }, '远程配置已加载,模块正常渲染')
},
})
</script>
<template>
<div style="max-width: 560px">
<BizErrorBoundary>
<RemoteWidget />
</BizErrorBoundary>
<div style="margin-top: 12px; display: flex; gap: 10px; align-items: center">
<ElSwitch v-model="ready" active-text="模拟远程配置加载完成" />
<ElTag size="small" type="info">先打开开关,再点兜底视图里的「重试」</ElTag>
</div>
</div>
</template>
显示代码
自定义兜底视图
#fallback 作用域插槽拿到 { error, retry } 自由定制(此处用 ElResult)。<script setup lang="ts">
/** 场景:自定义兜底视图——fallback 作用域插槽拿到 error 与 retry 自由定制 */
import { defineComponent, ref } from 'vue'
import { ElButton, ElResult } from 'element-plus'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
const BrokenChart = defineComponent({
name: 'BrokenChart',
render() {
throw new Error('图表库初始化失败')
},
})
const errorText = ref('')
</script>
<template>
<div style="max-width: 560px">
<BizErrorBoundary show-retry>
<BrokenChart />
<template #fallback="{ error, retry }">
<ElResult icon="warning" title="图表加载失败" :sub-title="error.message">
<template #extra>
<ElButton type="primary" size="small" @click="errorText = String(error); retry()">重试</ElButton>
<ElButton size="small" @click="errorText = '已复制错误信息给技术支持'">反馈问题</ElButton>
</template>
</ElResult>
</template>
</BizErrorBoundary>
<p v-if="errorText" style="font-size: 12px; color: var(--el-text-color-secondary)">{{ errorText }}</p>
</div>
</template>
显示代码
错误上报
[17:08:03] 已上报:告警面板数据解析失败
error 事件接入埋点 / 监控平台(demo 打印上报记录)。<script setup lang="ts">
/** 场景:错误上报——error 事件接入埋点 / 监控平台(demo 打印到页面) */
import { defineComponent, ref } from 'vue'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
const BrokenPanel = defineComponent({
name: 'BrokenPanel',
render() {
throw new Error('告警面板数据解析失败')
},
})
const reports = ref<string[]>([])
const onReport = (err: Error): void => {
const time = new Date().toTimeString().slice(0, 8)
reports.value.unshift(`[${time}] 已上报:${err.message}`)
}
</script>
<template>
<div style="max-width: 560px">
<BizErrorBoundary @error="onReport">
<BrokenPanel />
</BizErrorBoundary>
<div style="margin-top: 12px; font-size: 13px; color: var(--el-text-color-secondary)">
<div v-for="(r, i) in reports.slice(0, 5)" :key="i">{{ r }}</div>
<div v-if="reports.length === 0">错误发生后这里出现上报记录</div>
</div>
</div>
</template>
显示代码
模块隔离
✓ 稳定模块运行正常
左右两栏独立边界:一栏崩溃另一栏继续工作。
<script setup lang="ts">
/** 场景:模块隔离——左右两栏独立边界,一栏崩溃另一栏继续工作 */
import { defineComponent, h } from 'vue'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
const BrokenModule = defineComponent({
name: 'BrokenModule',
render() {
throw new Error('试验性功能渲染失败')
},
})
const NormalModule = defineComponent({
name: 'NormalModule',
setup: () => () =>
h('div', { style: 'padding: 18px; text-align: center; color: var(--el-color-success)' }, '✓ 稳定模块运行正常'),
})
</script>
<template>
<div style="max-width: 680px; display: grid; grid-template-columns: 1fr 1fr; gap: 14px">
<BizErrorBoundary text="试验性功能暂不可用">
<BrokenModule />
</BizErrorBoundary>
<BizErrorBoundary>
<NormalModule />
</BizErrorBoundary>
</div>
</template>
显示代码
纯兜底(无重试)
show-retry=false + 自定义文案,适合只读下线板块。<script setup lang="ts">
/** 场景:纯兜底展示——只读页面不提供重试(show-retry=false),并自定义文案 */
import { defineComponent } from 'vue'
import { BizErrorBoundary } from 'vue3-ep-biz-lib'
const BrokenBlock = defineComponent({
name: 'BrokenBlock',
render() {
throw new Error('该板块已下线')
},
})
</script>
<template>
<div style="max-width: 560px">
<BizErrorBoundary :show-retry="false" text="板块迁移中,请前往新版页面查看">
<BrokenBlock />
</BizErrorBoundary>
</div>
</template>
显示代码
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| show-retry | boolean | true | 兜底视图中是否展示「重试」按钮 |
| text | string | '内容渲染出错,请稍后重试' | 兜底视图文案 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| error | (error: Error) | 捕获到异常时触发(上报监控) |
Slots
| 插槽名 | 作用域 | 说明 |
|---|---|---|
| default | — | 被保护的子树 |
| fallback | { error: Error, retry: () => void } | 自定义兜底视图 |
Expose
| 名称 | 类型 | 说明 |
|---|---|---|
| retry | () => void | 清空错误重渲染子树 |
| error | Ref<Error | null> | 当前捕获的异常(响应式) |