|
|
@@ -2,11 +2,120 @@
|
|
|
|
|
|
# Vue.js
|
|
|
|
|
|
+## #15 Криптономикон-4 - Самостоятельная работа (валидации)
|
|
|
|
|
|
+<!-- 5 мин -->
|
|
|
+
|
|
|
+* [YouTube](https://www.youtube.com/watch?v=F7olyLbQeJo)
|
|
|
+* [RuTube](https://rutube.ru/video/ad58e437fbd7b1c072ee6c9634f2525c/)
|
|
|
+
|
|
|
+**Материалы к работе**
|
|
|
+
|
|
|
+* [Изменения в HTML](https://gitlab.com/vuejs-club/youtube-course/cryptonomicon-html/-/commit/85ac960b083c6138a3277164730f3a19b7b0dca3)
|
|
|
+* [Апи для загрузки списка монет](https://min-api.cryptocompare.com/data/all/coinlist?summary=true)
|
|
|
+* [Хуки жизненного цикла Vue](https://ru.vuejs.org/guide/essentials/lifecycle.html)
|
|
|
+
|
|
|
+
|
|
|
+## Асинхронность в JS, Promise
|
|
|
+
|
|
|
+Асинхронное программирование — концепция программирования, при которой результат выполнения функции доступен спустя некоторое время в виде асинхронного (нарушающего стандартный порядок выполнения) вызова. Запуск длительных операций происходит без ожидания их завершения и не блокирует дальнейшее выполнение программы.
|
|
|
+
|
|
|
+В современном JS асинхронность реализуется через [Promise (ожидание)](https://learn.javascript.ru/promise) (раньше для этого использовались callback-функции).
|
|
|
+
|
|
|
+Итак, функция, которая не может вернуть результат сразу (например, знакомый уже вам **fetch**), возвращает специальный объект **Promise** (в русскоязычном инете его часто так и называют - "промис").
|
|
|
+
|
|
|
+Когда результат будет получен, промис вызывает внутренние методы **fulfilled** при успешном завершении или **rejected** при ошибке (названия методов условные, они используются внутри промиса)
|
|
|
+
|
|
|
+Наружу у объекта "промис" выходит 3 метода:
|
|
|
+
|
|
|
+* **then** - при успешном выполнении "промиса"
|
|
|
+* **catch** - при ошибке
|
|
|
+* **finally** - при любом завершении работы
|
|
|
+
|
|
|
+В итоге вызов **fetch** может выглядеть примерно так:
|
|
|
+
|
|
|
+```js
|
|
|
+fetch(url).then(res => {
|
|
|
+ // здесь res строка, поэтому необходимо преобразовать ее в json-объект
|
|
|
+ if (res.ok) {
|
|
|
+ // метод json тоже асинхронный, поэтому мы возвращаем очередной промис
|
|
|
+ return res.json()
|
|
|
+ }
|
|
|
+ else throw new Error('Что-то пошло не так')
|
|
|
+}).then(json => {
|
|
|
+ return json
|
|
|
+}).catch(error => {
|
|
|
+ // можем извлечь текст ошибки и показать клиенту
|
|
|
+}).finally(() => {
|
|
|
+ // тут мы можем погасить какую-нибудь "крутилку", если запускали её перед fetch
|
|
|
+})
|
|
|
+```
|
|
|
+
|
|
|
+Выглядит достаточно грмоздко, поэтому придумали синтаксический сахар **async/await**
|
|
|
+
|
|
|
+## [Async/await](https://learn.javascript.ru/async-await)
|
|
|
+
|
|
|
+Ключевое слово **await** перед вызоыом функции говорит системе, что результат будет отложенным (функция вернёт "промис"). Чтобы система знала, что внутри функции используются **await** вызовы эта функция **должна** начинаться с ключевого слова **async**
|
|
|
+
|
|
|
+Например, код, который вы уже видели в прошлых заданиях:
|
|
|
+
|
|
|
+```js
|
|
|
+setInterval(async () => {
|
|
|
+ const f = await fetch(
|
|
|
+ `https://min-api.cryptocompare.com/data/price?fsym=${newTicker.name}&tsyms=USD&api_key=ce3fd966e7a1d10d65f907b20bf000552158fd3ed1bd614110baa0ac6cb57a7e`
|
|
|
+ )
|
|
|
+ const data = await f.json()
|
|
|
+ ...
|
|
|
+```
|
|
|
+
|
|
|
+>"Синтаксическим сахаром" называют код, который используют только при написании кода. Реальный JS-код преобразуется в "промисы" системой сборки (в одной из лекций мелькало слово "babel")
|
|
|
+
|
|
|
+К чему был весь этот бред? Чтобы вы понимали, что асинхронный код можно вызывать только в функции, объявленной как **async**. Т.е. не получится прямо в `<script setup>` написать `await fetch`. Нужно либо использовать синтаксис с "промисами", либо использовать один из методов жизненного цикла и объявив его асинхронным вызывать **await** методы в нем
|
|
|
+
|
|
|
+```js
|
|
|
+onMounted(async () => {
|
|
|
+ const f = await fetch(
|
|
|
+ 'https://min-api.cryptocompare.com/data/all/coinlist?summary=true'
|
|
|
+ )
|
|
|
+ const data = await f.json()
|
|
|
+ if (data.Response == 'Success') {
|
|
|
+ valutes.value = Object.keys(data.Data)
|
|
|
+ }
|
|
|
+})
|
|
|
+```
|
|
|
|
|
|
---
|
|
|
|
|
|
**Задание**
|
|
|
|
|
|
+1. Пересмотреть видео `#15 Криптономикон-4 - Самостоятельная работа (валидации)` и реализовать домашнее задание:
|
|
|
+
|
|
|
+ * не давать добавлять уже существующую валюту (показывать ошибку)
|
|
|
+ * при редактировании названия валюты очищать ошибку
|
|
|
+ * при вводе названия валюты выводить подсказку из 4-х похожих валют
|
|
|
+
|
|
|
+ При получении списка валют в `Data` приходит объект, ключами которого являются названия валют. Содержимое нам пока вроде не нужно, поэтому массив валют можно извлеч методом `keys`:
|
|
|
+
|
|
|
+ ```js
|
|
|
+ if (data.Response == 'Success') {
|
|
|
+ valutes.value = Object.keys(data.Data)
|
|
|
+ }
|
|
|
+ ```
|
|
|
+
|
|
|
+ Для получения 4-х подходящих валют можно использовать [вычисляемые свойства](https://ru.vuejs.org/guide/essentials/computed.html):
|
|
|
+
|
|
|
+ ```js
|
|
|
+ const shortValutes = computed(() => {
|
|
|
+ return valutes.value.filter(v => v.includes(ticker.value.toUpperCase())).slice(0,4)
|
|
|
+ })
|
|
|
+ ```
|
|
|
+
|
|
|
+ Вычисляемое свойство обновляется при изменении реактивных переменных используемых при вычислении (в нашем случае это `ticker`), т.е. при редактировании тикера массив валют будет переформировываться.
|
|
|
+
|
|
|
+ * при клике на подсказку добавлять валюту из подсказки
|
|
|
+ * учитывать регистр
|
|
|
+
|
|
|
+
|
|
|
+1. Прочитать и осознать [Хуки жизненного цикла Vue](https://ru.vuejs.org/guide/essentials/lifecycle.html)
|
|
|
|
|
|
[Назад](./web_06.md) | [Дальше](./web_08.md)
|