Книга рецептовbeta
- Введение
- Добавление свойств экземпляра
- Валидация форм
- Редактируемая система SVG-иконок
- Создание блога, управляемого CMS
- Модульное тестирование Vue-компонентов
- Создание пользовательской директивы прокрутки
- Отладка в VS Code
- Используем axios для доступа к API
- Устранение утечек памяти
- Хранение данных на стороне клиента
- Публикация Vue-компонентов в npm
- Интегрируем Docker в приложение Vue.js
- Практическое использование слотов с ограниченной областью видимости с GoogleMaps
Эта документация для версий v2.x и ранее. Для v3.x, документация на русском здесь.
Добавление свойств экземпляра
Простой пример
Могут быть данные/утилиты, которые планируете использовать во многих компонентах, но не хотите при этом загрязнять глобальную область видимости. В этих случаях вы можете сделать их доступными для каждого экземпляра Vue, указав их в прототипе:
|
Теперь $appName доступно во всех экземплярах Vue, даже до создания. Если мы запустим:
|
Тогда "Моё приложение" будет выведено в консоль!
Важность именования свойств экземпляра
Вам может быть интересно:
«Почему
appNameначинается$? Это важно? Что это даёт?»
Никакой магии здесь нет. $ — это соглашение, которое Vue использует для свойств, доступных во всех экземплярах. Это позволяет избежать конфликтов с любыми объявленными свойствами в data, вычисляемыми свойствами или методами.
«Конфликты? Что вы имеете ввиду?»
Ещё один хороший вопрос! Допустим, если вы установили:
|
Тогда что вы ожидаете будет выведено в консоль в примере ниже?
|
Будет выведено "Моё приложение", а затем "Название какого-то другого приложения", потому что this.appName (в каком-то роде) будет перезаписан свойством data после создания экземпляра. Мы именуем свойства экземпляра с $ чтобы избежать такого. Вы даже можете использовать своё собственное соглашение по именованию, если хотите, например $_appName или ΩappName, для предотвращения конфликтов с плагинами или будущими функциями.
Пример из жизни: замена Vue Resource на axios
Предположим, вы заменяете ушедший на пенсию Vue Resource. Но вам очень понравился доступ к методам запросов через this.$http и вы хотите получить аналогичное с axios.
Всё, что вам нужно сделать — это добавить axios в ваш проект:
|
И связать axios со свойством Vue.prototype.$http:
|
Теперь вы можете использовать такие методы как this.$http.get в любом экземпляре Vue:
|
Контекст методов прототипа
Если вы не знаете, то методы, добавленные в прототип, в JavaScript получают контекст экземпляра. Это означает, что они могут использовать this для доступа к свойствам data, вычисляемым свойствам, методам, или чему-либо ещё, объявленному в экземпляре.
Воспользуемся этой возможностью в методе $reverseText:
|
Обратите внимание, что привязка к контексту не будет работать, если вы используете стрелочные функции ES6/2015, поскольку они неявно связываются с родительской областью видимости. Это означает, что вариант со стрелочной функцией:
|
Закончится ошибкой:
|
Когда избегать этого паттерна
Пока вы внимательно следите за контекстом свойств прототипа, использование этого паттерна вполне безопасно и не добавит никаких багов.
Однако, иногда это может привести к путанице с другими разработчиками. Например, они могут увидеть this.$http и подумать «О, я и не знал об этой возможности Vue!». Затем они переходят на другой проект и не понимают, почему this.$http будет undefined. Или, может быть они хотят найти в Google как сделать что-либо, но ничего не могут найти, потому что не понимают, что на самом деле это всего лишь псевдоним для axios.
Удобство приходит за счёт очевидности. При просмотре компонента невозможно сказать откуда появился $http. Возможность Vue? Плагин? Добавил коллега?
Итак, какие есть альтернативы?
Альтернативы
Если не используем модульную систему
В приложениях без модульной системы (такой как Webpack или Browserify), существует паттерн, который часто используется в любом случае расширения фронтенда на JavaScript: глобальный объект App.
Если то, что вы хотите добавить, не имеет ничего общего с Vue, это может стать хорошим местом для расположения подобной логики. Вот пример:
|
Если вас удивило использование Object.freeze, то он предотвращает изменение объекта в будущем. Это по сути делает все свойства объекта константами, защищая вас от появления ошибок изменения состояния.
Теперь источник этих общих свойств можно увидеть явно: есть объект App, объявленный где-то в приложении. Найти его разработчики смогут поиском по проекту.
Другим преимуществом будет то, что App теперь можно использовать где угодно в вашем коде, независимо от того относится ли он к Vue или нет. Это включает привязку значений напрямую к свойствам экземпляра, вместо того, чтобы вводить функцию для доступа к свойствам в this:
|
Если используем модульную систему
Когда вы используете модульную систему, вы можете легко организовывать общий код в отдельные модули, а затем подключать их через require/import там где они нужны. В таком варианте больше ясности, потому что в каждом файле вы получаете список зависимостей. Вы знаете наверняка откуда что используется.
Хотя этот подход несколько многословнее, но он наиболее удобен для поддержки, особенно при работе с другими разработчиками и/или создании больших приложений.