Время чтения: 2 мин.
Вот минимальная реализация компонента Error Boundary, который использует два слота: один для обычного состояния и один для отображения ошибки:
<template>
<div>
<slot v-if="!error" name="default"></slot>
<slot v-else name="error" :error="error">
<!-- Fallback content if error slot is not provided -->
<div style="color: red; padding: 1rem; border: 1px solid red;">
Произошла ошибка: {{ error.message }}
</div>
</slot>
</div>
</template>
<script>
export default {
name: 'ErrorBoundary',
data() {
return {
error: null
}
},
errorCaptured(err, vm, info) {
this.error = err
// Останавливаем распространение ошибки
return false
},
methods: {
reset() {
this.error = null
}
}
}
</script>
Как использовать этот компонент
<template>
<div>
<ErrorBoundary>
<!-- Основной контент -->
<template #default>
<ComponentThatMightCrash />
</template>
<!-- Кастомное отображение ошибки (необязательно) -->
<template #error="{ error }">
<div class="custom-error">
<h3>Упс! Ошибка</h3>
<p>{{ error.message }}</p>
<button @click="$event.target.closest('error-boundary').__vue__.reset()">
Попробовать снова
</button>
</div>
</template>
</ErrorBoundary>
</div>
</template>
<script>
import ErrorBoundary from './ErrorBoundary.vue'
import ComponentThatMightCrash from './ComponentThatMightCrash.vue'
export default {
components: {
ErrorBoundary,
ComponentThatMightCrash
}
}
</script>
<style>
.custom-error {
padding: 1rem;
background: #ffebee;
border: 1px solid #ffcdd2;
border-radius: 4px;
}
</style>
Особенности этой реализации:
- Два именованных слота:
#default
— для основного контента#error
— для отображения ошибки (с передачей объекта ошибки как параметр)
- Автоматический fallback: если слот
error
не указан, показывается простое сообщение об ошибке - Метод
reset()
для сброса состояния ошибки - Очень простая логика — только самое необходимое для отлова и отображения ошибок
Эта реализация подходит для большинства базовых случаев, когда нужно просто защитить часть приложения от падений.
Добавить комментарий