В этой статье я хотел бы описать встроенные методы обработки ошибок существующие во Vue.js. Очевидно, что я не опишу каждый возможный сценарий, но я надеюсь, что эта статья поможет познакомиться с работой с ошибками во Vue.js!
Чтобы протестировать различные методы обработки ошибок, я решил использовать три разных типа ошибок. Первый просто ссылка на переменную, которой не существует:
<div id="app" v-cloak> Hello, {{name}} </div>
Этот пример не будет отображать ошибку для пользователя, он должен выводить предупреждение [Vue warn] в консоль.
Вы можете просмотреть этот пример здесь:
Для второго примера я попытался связать переменную с вычисляемым свойством, которая выводит ошибку:
<div id="app" v-cloak> Hello, {{name2}} </div> <script> const app = new Vue({ el:'#app', computed:{ name2() { return x; } } }) </script>
Этот код так же выдает [Vue warn] и обычную ошибку в консоли но при этом ничего не показывает пользователю в окне браузера.
Вот код для него.
Для третьей ошибки я использовал метод, который выдает ошибку при выполнении.
<div id="app" v-cloak> <button @click="doIt">Do It</button> </div> <script> const app = new Vue({ el:'#app', methods:{ doIt() { return x; } } }) </script>
Как и предыдущая, эта ошибка будет выводится дважды в консоли, одно предупреждение и одна ошибка. В отличие от прошлого раза, ошибка появляется только тогда, когда вы нажмете на кнопку.
И вот код для него:
Хорошо, прежде чем мы продолжим, я просто хочу прояснить, что эта выборка не репрезентативно для каждого типа ошибок, которые можно создать, это всего лишь базовый показатель из нескольких вариантов, который, я думаю, достаточно распространены в приложениях Vue.js.
Итак, как вы обрабатываете ошибки в приложениях Vue? Я должен сказать, что был немного удивлен, что в главном Vue Guide не было четко определенного раздела по обработке ошибок.
Да, есть общее описание в руководстве, но текст достаточно короткий, и весь может поместиться в одну цитату:
Если во время рендеринга компонента возникает ошибка выполнения, она будет передана в глобальную конфигурационную функцию Vue.config.errorHandler(если она была задействована). Возможно, было бы неплохо использовать этот хук вместе с сервисом отслеживания ошибок, таким как Sentry, который обеспечивает официальную интеграцию для Vue.
На мой взгляд, эта тема должна быть описана более подробно в документации. В общем, обработка ошибок в Vue сводится к следующим методам:
Первый метод, который мы рассмотрим, это errorHandler. Как вы можете догадаться, это общий обработчик ошибок для приложений Vue.js. Его использование выглядит так:
Vue.config.errorHandler = function(err, vm, info) { }
В приведенном выше объявлении переменная err — это фактический объект ошибки, info — это строка ошибки, специфичная для Vue, а vm — фактическое приложение Vue. Помните, что одновременно на одной веб-странице может работать несколько приложений Vue. Этот обработчик ошибок будет применяться ко всем из них. Рассмотрим этот простой пример:
Vue.config.errorHandler = function(err, vm, info) { console.log(`Error: ${err.toString()}\nInfo: ${info}`); }
Для первого примера кода эта обработка ошибки ничего не делает. Если вы помните, оно выдает предупреждение, а не ошибку.
Для второго примера кода, она обработает ошибку и выдаст сообщение:
Error: ReferenceError: x is not defined Info: render
Наконец, для третьего примера она выдаст такой сообщение:
Error: ReferenceError: x is not defined Info: v-on handler
Теперь давайте проверим следующий метод.
warnHandler Vue предупреждения. Обратите внимание, что этот обработчик игнорируется во время режима продакт. Обработчик метода также немного отличается:
Vue.config.warnHandler = function(msg, vm, trace) { }
Переменные msg, и vm самоочевидны, а trace содержит дерево компонентов. Рассмотрим этот пример:
Vue.config.warnHandler = function(msg, vm, trace) { console.log(`Warn: ${msg}\nTrace: ${trace}`); }
Первый пример кода теперь обрабатывается и выдает предупреждения:
Warn: Property or method 'name' is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties. Trace: (found in <Root>)
Второй и третий примеры не меняются. Вы можете просмотреть работу примером ниже:
Третий метод, который я продемонстрирую, это renderError. В отличие от предыдущих двух, этот метод используется только внутри компонентов, а не глобально. Также, как warnHandler, он отключен в режиме продакт.
Чтобы его использовать, нужно описать его в компоненте или приложение. Пример использования:
const app = new Vue({ el:'#app', renderError (h, err) { return h('pre', { style: { color: 'red' }}, err.stack) } })
Если он использовать в первом примере с ошибкой, он ничего не делает, так как первый выдает предупреждение, а не ошибку. Если вы задействуете его во втором, c вычисляемым свойством то будет вывод ошибки на экрана браузера. Вы можете увидеть это в коде ниже.
Честно говоря, я не уверен, для каких целей я бы использовал этот метод. На мой взгляд консоль более подходящее место для вывода ошибок, но если ваша команда QA или другие тестировщики не знакомы с консолью браузера, этот метод может помочь вывести сообщение об ошибке на экране.
Финальный (специфичной для Vue) метод errorCaptured. В документации о нем сказано:
Вызывается, когда фиксируется ошибка любого потомка компонента. Хук получает три аргумента: ошибку, экземпляр компонента, который вызвал ошибку, и строку, содержащую информацию о том, где была зафиксирована ошибка. Хук может вернуть false, чтобы предотвратить дальнейшее распространение ошибки.
Основываясь на моих исследованиях (я определенно шокирован этим), этот обработчик ошибок должен использоваться только «родительским» компонентом, обрабатывающим ошибку «дочернего» компонента. Насколько я знаю, его нельзя использовать в основном экземпляре Vue, только в компоненте с дочерними элементами.
Чтобы проверить этот метод, я создал родительский / дочерний набор компонентов, например:
Vue.component('cat', { template:` <div><h1>Cat: </h1> <slot></slot> </div>`, props:{ name:{ required:true, type:String } }, errorCaptured(err,vm,info) { console.log(`cat EC: ${err.toString()}\ninfo: ${info}`); return false; } }); Vue.component('kitten', { template:'<div><h1>Kitten: </h1></div>', props:{ name:{ required:true, type:String } } });
Обратите внимание, что в компоненте kitten есть ошибка. Теперь, если я попытаюсь использовать:
<div id="app" v-cloak> <cat name="my cat"> <kitten></kitten> </cat> </div>
Я получу сообщение от обработчика:
cat EC: TypeError: dontexist is not a function info: render
Вы можете просмотреть это в коде ниже.
Так что да … интересный метод. Я предполагаю, что он будет в основном использоваться людьми, создающими библиотеки компонентов с отношениями типа родительский / дочерний. Это скорее метод «разработчика библиотеки», чем метод «обычного разработчика». Но опять же — это только мое первоначальное впечатление от этого метода.
Последний (и самый мощный) вариант — использование window.onerror, глобальный обработчик ошибок для всего, что может пойти не так с вашим JavaScript. Обработчик имеет форму:
window.onerror = function(message, source, line, column, error) { }
Вероятно, единственное,о чем вы не можете догадаться, это что такое переменная source. В ней содержится URL скрипта. Здесь все становится интереснее. Если вы определите этот метод и не используете Vue.config.errorHandler, то он не будет работать. Vue ожидает, что вы определите errorHandler а, если вы этого не сделаете, не распространит ошибку за пределы себя.
Вот пример использование этого метода. Я закомментировал ошибку в errorHandler, но если вы удалите комментарий, вы увидите, что глобальный обработчик ошибок не запускается. Единственное, что вы можете увидеть — запуск глобального обработчика, при нажатие на вторую кнопку.
Я надеюсь, что эта статья была для вас полезна. Мне бы очень хотелось услышать, как люди используют эти методы в своих приложениях!
Перевод статьи: Handling Errors in Vue.js
Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…
Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…
Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…
Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…
Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…
Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…
View Comments
Спасибо за полезную статью!