Евгений Колесников пре 1 година
родитељ
комит
c9b6574ff1
5 измењених фајлова са 222 додато и 443 уклоњено
  1. 14 25
      articles/web_04.md
  2. 207 418
      articles/web_05.md
  3. BIN
      img/web_015.png
  4. BIN
      img/web_016.png
  5. 1 0
      readme.md

+ 14 - 25
articles/web_04.md

@@ -30,13 +30,11 @@
 
 1. [Исходный HTML/CSS для самостоятельного повторения](https://gitlab.com/vuejs-club/youtube-course/cryptonomicon-html)
 1. Материалы к изучению: под роликом на ютубе куча ссылок, но в принципе там раздел "Основы" от [Синтаксиса шаблонов](https://v3.ru.vuejs.org/ru/guide/template-syntax.html) до "Работы с формами"
-1. [Исходный код урока](https://gitlab.com/vuejs-club/youtube-course/cryptonomicon/-/tree/lesson1)
 1. [API для получения ключа:](https://www.cryptocompare.com/)
 
 **Расшифровка скринкаста** (вольный пересказ своими словами)
 
->**Внимание**, сегодня мы с вами напишем очень и очень плохой код почему так и зачем мы это
-сделаем мы это сделаем потому что когда вас учат писать сразу хороший код вас учат решать задачу одним способом рано или поздно вы сталкиваетесь задач и решения которые вы не знаете и оказываетесь ситуации когда не понимаете хорошие ваше решение или плохое мы с вами вначале напишем плохой но к сожалению распространенный код и шаг за шагом в рамках этой серии видео будем его улучшать у нас как и в реальной жизни будут появляться новые требования заказчика мы будем находить какие-то баги сами уже у себя и сами героический фиксить и так далее таким образом на выходе вы не только получите хороший код для решения этой задачи но и понимание как глядя на код понять что он действительно плохой 
+>**Внимание**, сегодня мы с вами напишем очень и очень плохой код почему так и зачем мы это сделаем мы это сделаем потому что когда вас учат писать сразу хороший код вас учат решать задачу одним способом рано или поздно вы сталкиваетесь задач и решения которые вы не знаете и оказываетесь ситуации когда не понимаете хорошие ваше решение или плохое мы с вами вначале напишем плохой но к сожалению распространенный код и шаг за шагом в рамках этой серии видео будем его улучшать у нас как и в реальной жизни будут появляться новые требования заказчика мы будем находить какие-то баги сами уже у себя и сами героический фиксить и так далее таким образом на выходе вы не только получите хороший код для решения этой задачи но и понимание как глядя на код понять что он действительно плохой 
 
 >В рамках расшифровки скринкаста я сразу буду переписывать его на Vue3, используя `vite` + `script setup`
 
@@ -44,11 +42,9 @@
 
 Чем же мы с вами займемся? Мы с вами напишем небольшое приложение, которое позволяет добавлять в список отслеживания криптовалюты, используя **api** `cryptocompare.com`.
 
-Соответственно мы будем иметь возможность добавить криптовалютные пары "имя валюты - USD" в наблюдение и, когда мы выбираем конкретную валюту, у нас внизу появляется график отслеживания. Мы можем убрать выбрать другую пару и вот сейчас постепенно шаг обновления 1 5 секунд у нас будут появляться собственно данные
-о изменение вот соответственно график автоматически адаптируется под минимальные и максимальные значения поэтому в начале он может выглядеть странно но со временем он нормализуется. 
+Соответственно мы будем иметь возможность добавить криптовалютные пары "имя валюты - USD" в наблюдение и, когда мы выбираем конкретную валюту, у нас внизу появляется график отслеживания. Мы можем убрать выбрать другую пару и вот сейчас постепенно шаг обновления 1 5 секунд у нас будут появляться собственно данные о изменение вот соответственно график автоматически адаптируется под минимальные и максимальные значения поэтому в начале он может выглядеть странно но со временем он нормализуется. 
 
-График нам не очень интересно всем мы можем что-то удалить мы можем добавить криптовалюту мы можем так далее ну и когда мы обновляем страницу у нас очевидно встречает пустой экран вот мы добавляем в начале черточка когда нету данных и потом когда данные приезжают кто у нас там еще есть bitcoin кэш допустим у нас будут вот обновляться что у нас есть на входе на входе дизайнер
-нам выдал вот такой вот завершены html с него мы и будем начинать и он и ставит станет нашей отправной точкой 
+График нам не очень интересно всем мы можем что-то удалить мы можем добавить криптовалюту мы можем так далее ну и когда мы обновляем страницу у нас очевидно встречает пустой экран вот мы добавляем в начале черточка когда нету данных и потом когда данные приезжают кто у нас там еще есть bitcoin кэш допустим у нас будут вот обновляться что у нас есть на входе на входе дизайнер нам выдал вот такой вот завершены html с него мы и будем начинать и он и ставит станет нашей отправной точкой 
 
 ### Создание нового проекта, удаление лишего
 
@@ -98,7 +94,7 @@
 
 Сегодня все наше внимание будет приковано к файлику `App.vue`. 
 
-Итак, что нам надо? Будем двигаться сверху вниз,     оживляя эту страницу. Первое что нам надо это научиться заполнять поле "Тикер" и, когда нажимается кнопка "добавить", реагировать на нажатие.
+Итак, что нам надо? Будем двигаться сверху вниз, оживляя эту страницу. Первое что нам надо это научиться заполнять поле "Тикер" и, когда нажимается кнопка "добавить", реагировать на нажатие.
 
 Как мы помним, сильной стороной **Vue** является так называемое **двухстороннее связывание**, когда мы можем определить что-то в данных java-скрипта и вывести это что-то на экран. И когда что-то на экране поменяется оно автоматически изменится в приложении. 
 
@@ -143,8 +139,7 @@ const ticker = ref('default')
 Как бы мы это делали в обычном java-скрипте? Мы нашли бы элемент на страничке через query-селектор, добавили слушатель на события клик и после этого сказали бы
 какую функцию вызывать.
 
-Во вью все работает похожим образом. Мы пишем `v-on:click="..."` (мы говорили что все атрибуты **vue** начинаются с `v-`), дальше имя события клик. Мы здесь можем
-написать к примеру обычный java-скрипт код (`"ticker = 123"`) и смотрите нажимаю кнопку "добавить", видите в переменную `ticker` записалась значение `123` и она автоматически изменилась.
+Во вью все работает похожим образом. Мы пишем `v-on:click="..."` (мы говорили что все атрибуты **vue** начинаются с `v-`), дальше имя события клик. Мы здесь можем написать к примеру обычный java-скрипт код (`"ticker = 123"`) и смотрите нажимаю кнопку "добавить", видите в переменную `ticker` записалась значение `123` и она автоматически изменилась.
 
 Но согласитесь писать код прямо в верстке как то супер странно, поэтому мы хотим чтобы код можно было писать рядом с вёрсткой (вспоминаем про **SFC**)
 
@@ -164,8 +159,7 @@ function add () {
 </script>
 ```
 
-Обратите внимание здесь можно будет потом передавать аргументы, то есть в 99% случаях надпись `add` и `add()` абсолютно одинаковы, то есть если **vue** видит надпись, что при событий клик вызов функции `add`, он понимает что
-это функцию надо вызвать а если он видит вот так `add()` "о, это же выражение я вот беру и вызываю функцию add".
+Обратите внимание здесь можно будет потом передавать аргументы, то есть в 99% случаях надпись `add` и `add()` абсолютно одинаковы, то есть если **vue** видит надпись, что при событий клик вызов функции `add`, он понимает что это функцию надо вызвать а если он видит вот так `add()` "о, это же выражение я вот беру и вызываю функцию add".
 
 Итак пробуем: выводится алерт
 
@@ -190,8 +184,7 @@ function add () {
     ...
 ```
 
-Дальше реализуем список тикеров. Очевидно что нам надо как-то научиться повторять какие-то вещи.
-Очевидно что повторять нам надо что то, что то это скорее всего будет массивом.
+Дальше реализуем список тикеров. Очевидно что нам надо как-то научиться повторять какие-то вещи. Очевидно что повторять нам надо что то, что то это скорее всего будет массивом.
 
 Создадим в скрипте массив тикеров: просто объявляем переменную
 
@@ -203,8 +196,7 @@ const tickers = ref([1, 2, 3, 4])
 
 Как сказать **vue** "повтори какую-то вещь несколько раз"?
 
-Во-первых, что за вещь мне надо повторять? Нужно в верстке найтие место, которое повторяется, удалить лишние повторы и использовать так называемую структурную директиву (директивами называются атрибуты которые обрабатываются **vue** опять же существенное упрощение но пока сойдет и
-так) `v-for`. У нас есть две ключевые структурные
+Во-первых, что за вещь мне надо повторять? Нужно в верстке найтие место, которое повторяется, удалить лишние повторы и использовать так называемую структурную директиву (директивами называются атрибуты которые обрабатываются **vue** опять же существенное упрощение но пока сойдет и так) `v-for`. У нас есть две ключевые структурные
 директивы мы потом поговорим почему они являются структурными но пока запомнить `v-for` и `v-if` они настолько суровы что даже друг с другом не дружат.
 
 `v-for` работает точно также как цикл `for of` (или `for in`)...
@@ -239,8 +231,7 @@ const tickers = ref([1, 2, 3, 4])
 
 Давайте чуть-чуть доведем до ума, но перед этим сделаем маленький шаг назад дело в том что в мире **vue** огромное количество раз вы будете писать в `v-bind` и `v-on`.
 
-Писать вот так очень многословно поэтому придумали так называемую короткую запись отдельные люди называют
-их ярлыками, когда вместо `v-on` мы пишем собаку `@`, а вместо `v-bind` просто ничего не пишут, оставляют только  `:`.
+Писать вот так очень многословно поэтому придумали так называемую короткую запись отдельные люди называют их ярлыками, когда вместо `v-on` мы пишем собаку `@`, а вместо `v-bind` просто ничего не пишут, оставляют только  `:`.
 
 Хорошо уже похоже на правду давайте мы сделаем еще что-то а что ещё нам же надо выводить у нас тут какой-то глупый массив только со строками. 
 
@@ -269,8 +260,7 @@ const tickers = ref([
 
 #### Добавление элементов
 
-Давайте научимся для начала добавлять такие элементы плюс давайте приведем это всё в тот дизайн который
-был а именно добавим USD в пару:
+Давайте научимся для начала добавлять такие элементы плюс давайте приведем это всё в тот дизайн который был а именно добавим `USD` в пару:
 
 ```vue
 <dt class="text-sm font-medium text-gray-500 truncate">
@@ -292,8 +282,7 @@ function add () {
 
 >Не забываем, что обращение к значению реактивной переменной происходит через свойство `.value`
 
-Хорошо теперь только нам осталось вместо имени
-подставить название нового тикера:
+Хорошо теперь только нам осталось вместо имени подставить название нового тикера:
 
 ```js
 function add () {
@@ -306,8 +295,7 @@ function add () {
 }
 ```
 
-Теперь хочется очищать тикер когда он добавился в массив. Вспомним что у нас связь и двухсторонняя
-и просто запишем в тикер пустую строку нажимаем добавить и вот все испарилось
+Теперь хочется очищать тикер когда он добавился в массив. Вспомним что у нас связь и двухсторонняя и просто запишем в тикер пустую строку нажимаем "добавить" и вот все испарилось
 
 ```js
 function add () { 
@@ -362,7 +350,8 @@ function handleDelete (tickerToRemove) {
 ## Итоги
 
 Сегодня мы с вами:
-* познакомились со структурой vue файла
+
+* познакомились со структурой **vue** файла (скрипт и шаблон)
 * научились добавлять в скрипт функции и реактивные переменные
 * научились двухстороннему связыванию с помощью директивы `v-model`
 * научились подписываться на события через `v-on` или краткую запись `@`

+ 207 - 418
articles/web_05.md

@@ -11,433 +11,222 @@
 
 * [Исходный HTML/CSS для самостоятельного повторения](https://gitlab.com/vuejs-club/youtube-course/cryptonomicon-html)
 * [реактивность во Vue3:](https://ru.vuejs.org/guide/essentials/reactivity-fundamentals.html)
-* [Исходный код урока](https://gitlab.com/vuejs-club/youtube-course/cryptonomicon/-/tree/lesson2)
 * [API для получения ключа:](https://www.cryptocompare.com/)
 
 **Расшифровка скринкаста:**
 
->**Дисклеймер** Код который мы пишем в рамках этого урока все еще является недостаточно хорошим для продакшена. Прежде чем пытаться нести эту практику в реальные проекты пожалуйста посмотрите серию видео с разработкой этого приложения до конца
-
-Мы с вами освоили _добавление_ и _удаление_ элементов. Давайте добавим еще и выбор потому что
-при выбранном элементе должен отображаться вот этот график
-
-
-
- с этим
-достаточно просто мы берем и говорим так
-выбор выбранный элемент изменяется с
-течением времени когда мы слышим что
-что-то меняется с течением времени мы
-говорим это состояние назову его sale
-первоначально ничего не выбрано поэтому
-ну хорошо и очевидно что при клике по
-элементу я хочу выбирать записывать в
-сел то что было выбрано да' поэтому игры
-вот мой before en-tee-ter си при клике
-записывать и заодно демонстрируя что вот
-здесь можно писать
-напоминают шрифтовые выражения не только
-вызовы функций как мы проверим что у
-меня что-то выбралось давайте для теста
-выведем сау вот так обновлю страничку и
-вот видите действительно меняется и
-теперь я могу дописать логику чтобы вот
-этот блок отображался только когда у
-меня есть сау вот это section
-если сел и точно также
-извините давайте писать правильно и он
-говорит так вы их пожалуйста давайте мы
-разместим дом и говорю что при клике на
-кнопочку устанавливаем
-сел вынул проверяем выбралась закрылась
-работает круто правда
-убираю вывод нашего сел
-хорошо двигаемся дальше в нашем случае
-мы хотим чтобы у нас выделялись цветом
-как происходит выделение цветом у нас
-тут написано что видите border иметь
-цвет карпова 700 он solid единственное
-чего нам не хватает css класса который
-указывает толщину борта ран
-как же мы это делаем мы уже знаем что
-для того чтобы прицепить
-атрибут к классу мы можем написать :
-глаз и здесь мы можем написать если села
-равен т то пустая the border 4 в
-противном случае пустая строка мы не
-можем здесь написать их почты их ничего
-не возвращает
-а так у нас будет жива скриптовые
-выражение до тернарный оператор
-смотрите 1 работает здесь я хочу
-обратить ваше внимание на то что это
-абсолютно нормально совмещать в одном
-определении
-просто допустим класс через равно и
-через двоеточие
-это означает что вот эта статическая
-часть это динамическое текст но
-согласитесь выглядит дико уродливо
-поэтому для классов view предлагает
-несколько синтаксиса синтаксис массивов
-с ним можете ознакомиться сами он менее
-распространен
-а часто же используют так называемый
-объектный синтаксис когда мы здесь пишем
-объект в котором ключами являются имена
-классов в моем случае the border 4 а
-значением логическое выражение который
-отвечает надо ли добавлять этот класс
-или нет то есть я пишу вот так и это
-читается добавь класс border 4 если сел
-равен то обратите внимание здесь точно
-также может быть вызов метод
-а вот мы добились желаемого так и
-давайте оживим чтобы здесь было не везде
-раз мы теперь знаем а мы можем написать
-сел на эбу
-обновляем и 50 м от вадима 3 так жмем
-dima 2
-удалить ой а как так получилось что
-нажал кнопку удалить а выбралась
-происходит это потому что так работает
-жира скрипт
-да вы кликаете на кнопочку которая
-находится здесь
-генерируется события и это событие как
-вы прекрасно знаете начинает всплывать
-что означает всплытия события для нас
-оно означает что все элементы в которые
-вложены это а это в том числе и наш
-элемент тоже получат события клик и
-соответственно будет нехорошо что мы
-можем сделать мы можем вспомнить что в
-удалить приходит ивенты сделать ему что
-мы делаем java скрипте стоп про погибшим
-до прекратить всплыть и новью и здесь
-нам помогает и поэтому у нас для клика
-где наша кнопочка удалить вот она точно
-также для всех событий есть модификатор
-стоп прекратить всплытие давайте
-проверим на всякий случай обновлю
-страничку ветер дома 2 больше не
-выбралась это не единственный
-модификатор со списком модификаторов
+>**Дисклеймер** Код который мы пишем в рамках этого урока все еще является недостаточно хорошим для продакшена. Прежде чем пытаться нести эту практику в реальные проекты пожалуйста посмотрите серию видео с разработкой этого приложения до конца.
+
+Мы с вами освоили _добавление_ и _удаление_ элементов. Давайте добавим еще и выбор, потому что при выбранном элементе должен отображаться график.
+
+С этим достаточно просто мы берем и говорим "выбранный элемент изменяется с
+течением времени". Когда мы слышим что что-то меняется с течением времени мы
+говорим это "состояние". Назову его _sel_. Первоначально ничего не выбрано поэтому `null`:
+
+```js
+    const sel = ref(null)
+```
+
+И очевидно, что при клике по элементу я хочу записывать в _sel_ то что было выбрано.
+
+```vue
+<div  
+    v-for="t in tickers"
+    :key="t"
+    @click="sel = t"
+```    
+
+Заодно демонстрируя, что здесь можно писать js-выражения, а не только
+вызовы функций.
+
+Как мы проверим что что-то выбралось? Давайте для теста выведем `sel` на страничке (вспоминаем про интерполяцию)
+
+![](../img/web_015.png)
+
+Теперь можно дописать логику чтобы график отображался только когда у меня есть `sel`
+
+```vue
+<section 
+    v-if="sel"
+    ^^^^^^^^^^
+    class="relative">
+    <h3 class="text-lg leading-6 font-medium text-gray-900 my-8">
+        VUE - USD
+```
+
+А при клике на кнопочку "закрыть" устанавливаем `sel = null`
+
+```vue
+<button
+    @click="sel = null"
+    ^^^^^^^^^^^^^^^^^^^
+    type="button"
+    class="absolute top-0 right-0"
+>
+    <svg
+```    
+
+Хорошо двигаемся дальше. В нашем случае мы хотим чтобы у нас выделялись цветом выбранная пара.
+Для этого нужно добавить css класс, который указывает толщину бордера.
+
+![](../img/web_016.png)
+
+Для того чтобы прицепить атрибут к классу мы можем написать `:class` и здесь мы можем js-выражение
+
+```vue
+<div  
+    v-for="t in tickers"
+    :key="t"
+    @click="sel = t"
+    :class="sel == t ? 'border-4' : ''"
+    class="bg-white overflow-hidden shadow rounded-lg border-purple-800 border-solid cursor-pointer"
+>
+```
+
+Здесь я хочу обратить ваше внимание на то что это
+абсолютно нормально совмещать в одном определении
+атрибут **class** через равно и через двоеточие.
+Это означает что вот первая часть статическая, а вторая динамическая.
+
+Но согласитесь, выглядит дико уродливо поэтому для классов **vue** предлагает несколько вариантов синтаксиса.
+
+* синтаксис массивов. с ним можете ознакомиться сами он менее распространен
+* объектный синтаксис, когда мы пишем объект в котором ключами являются имена классов (в моем случае `border-4`), а значением логическое выражение которое
+отвечает надо ли добавлять этот класс или нет
+
+    ```vue
+    :class="{
+        'border-4': sel == t
+    }
+    ```
+
+    это читается: "добавь класс border-4, если _sel_ равен `t`"
+
+    обратите внимание, в качестве логического выражения также может быть вызов метода 
+    
+    
+Вот мы добились желаемого. Давайте поправим заголовок графика, чтобы здесь было название валюты: `sel.name`
+
+
+```vue
+<h3 
+    class="text-lg 
+        leading-6 
+        font-medium 
+        text-gray-900 
+        my-8"
+>
+    {{ sel.name }} - USD
+</h3>
+```    
+
+Жмем удалить, ой а как так получилось что нажал кнопку удалить а выбралась пара? Происходит это потому что так работает java-скрипт. 
+
+Когда вы кликаете на кнопочку "удалить", генерируется события и это событие, как вы прекрасно знаете начинает "всплывать". 
+
+Что означает всплытия события для нас? Оно означает, что все элементы в которые вложены это а это в том числе и наш элемент тоже получат события клик и соответственно сработает выбор элемента
+
+Что мы можем сделать? Мы можем вспомнить что в "удалить" приходит событие `@click` и сделать ему что
+мы делаем в java скрипте: **stopPropagation**.
+
+**vue** и здесь нам помогает и поэтому у нас для клика
+где наша кнопочка "удалить" есть модификатор `.stop` -  прекратить всплытие
+
+```vue
+<button
+    @click.stop="handleDelete(t)"
+          ^^^^^
+```
+
+Это не единственный модификатор. Со списком модификаторов
 рекомендую ознакомиться самостоятельно
-хорошо теперь давайте пора начинать
-ходить за реальными данными для того
-чтобы ходить за реальными данными мне
-понадобится здесь кнопочка api до
-напоминаю что надо зарегистрироваться на
-крипто кампер чтоб получить бесплатный
-ключ
-очевидно что мне нужен price tag спасибо
-здесь у меня есть документация и вот
-здесь есть синглу символ прайс она
-передается f сам test the sims хорошо
-давайте сделаем так
-я беру и говорю цепь интервал
-буду каждые три секунды ходить на сервер
-дальше я говорю значит konce эфрона away
-ага ей мне пальца вы значит а sing
-сходив в чём на https mina pi крип так
-compair коп до the price tag дальше
-конечно же не помню совсем ивсем это из
-какого киккера получать это очевидно бти
-кир у нас лежит в переменной ньюте
-черный ему да вот который мы добавляли
-обратите внимание здесь нельзя
-использовать за стикер подумайте почему
-и the sims куда меня интересует везде и
-api ключ мы должны обязательно передать
-до переходим назад
-переходим в наши api ключ и и копирую
-его сюда чтобы прям его сюда и вставить
-так
-так дальше как мы знаем после
-результатов и чак надо дождаться f
-джейсон и давайте ради теста сделаем
-консоль log data посмотрим что нам там
-приходит открываем наше творение
-удаляем эти добавляем тикер убить icy
-ждём 3 секундочки и вот смотрите нам
-приходит
-витязь и везде хорошо
-берем и пишем new kicker .
-прайс равно дата .
-везде только давайте ну хотя давайте вот
-пробуем давайте вообще приведем наше
-приложение приличный вид то есть здесь
-делаем пусто
-удалим дефолтное значение и добавляем 5
-7 ничего нет подождите как же так вот у
-меня все выводилось берите действительно
-цена приходит как так то юпитер . прайс
-я туда записываю что получается не
-реактивно как же так рассказывали что
-view весь такой реактивный
-давайте попробуем чуть по другому
-зыс я беру в киккера ххх раз так найду
-пожалуй среди них тикер у которого имя
-такое же как у тизерные хотя странно и
-живот его просто пушил сюда iv прайс
-пишу дата везде ведь попробуем добавляем
-хитер ждём 3 секунды о заработало как
-так то получается тут мой реактивный тут
-нет придется разбираться
-но этим мы займемся в следующем видео
-давайте то пайку
-да какой который хайпанул согласитесь
-выглядит ужасно давайте сделаем красиво
-для того чтобы было красиво я напишу
-следующую логику что если да то и
-изгибаешь и единицы то есть цена больше
-одного доллара то выводе пожалуйста с
-точностью до двух знаков в противном
-случае выводе если оно меньше выводе с
-точностью два знака после запятой
-по два значащих знака the prestige едва
-означает что там может быть много много
-нулей некоторые монетки стоят достаточно
-дешево но там всегда будет ровно два
-значащих знака возьмите 0069
-это вот три знака по что первый нолик
-попроси шин витязь и круто работает
-хорошо самое время добавить график
-торговли сейчас видимо не идет потому
-что они ну медицина идет не так активно
-похоже потому что цена медленно
-изменяется давайте добавим график
-напоминаю что мы вот выделяем и вот
-здесь должен быть график соответственно
-говорим график для графика нужны данные
-эти данные изменяются с течением времени
-значит это что правильно состояния
-назову его угров это данные состояния
-хорошо теперь что я я такой смотрю ум
-когда у меня данные вот здесь обновились
-это рю если текущий выбранный элемент
-равен на моему секиру который обновлялся
-давайте может
-new new мне не очень нравится
-переименуем is new
-два первых давайте сделаем из граф push
-дата ее здесь сохранив график данные так
-хорошо и мне не очень не очень нравится
-эта операция при factory недоступна
-интересно почему я тогда не горды руками
-переименую назову его карен тикер здесь
-просто ради того чтобы было чуть-чуть
-более понятно что это такое карен ticker
-карен тикер коран ticker хорошо и
-давайте
-выводить график но график как мы будем
-выводить
-смотрите у нас же есть конкретная высота
-ячеек нас есть максимальная высота
-нам надо как то сделать так чтобы они не
-уходили ну то есть как то добить до этой
-высоты поэтому мы будем из управлять
-высотой с помощью тега style
-мы такие давайте возьмем как нам
-выводить историю очевидно с помощью
-тегов и for где один ген этот рисуется
-покажись мне вот она вот эти полосочки
-до удаляю оставляю одну удаляю тега h20
-класс аж 24 который отвечает за высоту
-этой в 1 пока оставлю его просто увидели
-и говорю что выводе
-эти девы с помощь для каждой бар полоска
-in граф сохраняю
-и он не жалуется что барни использован
-что в общем-то логично
-и мы два первых добавляем kay
-мы же помним что нам нужен
-когда у нас нету ничего отличительного
-уникального элемента мы можем взять
-индекс это не самая лучшая практика мы
-будем детально говорить о том что зачем
-и почему и будем пробовать
-сохраняем перезагружаем чтобы убрать вот
-эти вот старые наши творения
-добавляем 5 7 кликаем и ждем через три
-он смотрите пока эти полосочки не имеют
-правильной высоты но они уже появляются
-хотя бы
-теперь что касается правильной высоты я
-хочу воспользоваться точно так же как и
-биржу класс я могу сделать ставил и
-точно так же могу здесь передать объекте
-и сказать что хоть и высота очевидно что
-я буду управлять процентов при них не
-известны ни какие пиксели ничего не хочу
-хардкоре что высота будет допустим бар
-процент до
-так там не справедливо сказал а чего это
-ты тут поставил и горит человек этой
-кавычки забыл мы даже атрибут так но в
-графья что сохраняем настоящую цену
-сейчас скорее всего что-то пойдет не по
-плану ухухуху 447 тысяч триста девять
-процентов так нам нужно привести граф в
-божеский вид
-я задам нормала из граф создам функцию в
-которой что я сделаю я найду
-максимальное значение в моем графике
-масс макс из граф найду минимальное
-значение в моем графике и дальше сделаю
-следующее для каждого элемента графика
-поэтому map я возьму вычту из него
-минимальное минимальное значение
-иначе понимаете если я буду просто
-приводить в процентах то разницу в сотых
-долях вы не увидите на такой огромной
-цифры 47 1327
-вычту минимальное значение и разделю на
-разницу между максимальным значением и
-минимальным и что получить проценты
-умножу это на 100 только не 3 конечно a
-price
-так и теперь я буду рисовать график
-своим we forom где-то у меня вот он не
-от графа out нормала из графы тоже метод
-его надо вызвать давайте пробовать бить
-эссе добавляем так факир был пьяный
-фокус не удался давайте посмотрим что у
-нас за стиле здесь повешай уселись это
-ошибки повесь посыпались кино 3 тб
-рапорте name if we sell скажите мне
-не понятно давайте посмотрим кино 3 тб
-рапорте name of нал логично поэтому
-здесь может не быть текущего выделенного
-значения все конечно странно что это
-сейчас происходит но поставим ? да чтобы
-говорить что если у нас засел ну а это
-нормально чтобы он не пытался брать
-уныло поле name
-да заодно воспользовались современным
-чего скриптовом синтаксисом смотрим
-давайте обновим страницу кем всегда
-держите консоль открытое и отведите мы
-сейчас не держали пропустили что-то
-интересное так пока работает ну что ж со
-стилями посмотрите хайд 0 хоть 102
-отведите он начал двигаться вот только
-согласитесь вот этот хит 0 ведь их
-bitcoin растет поэтому вот здесь
-оказалась минимальной зачем выглядит
-достаточно уродливо давайте мы чуть-чуть
-с че че рим и добавим следующее что 5
-процентов высоты будет всегда
-поэтому мы говорим что прайс это 5 + и
-умножаем не на 101 95 ну то есть нижняя
-часть полосочки будет всегда ноги
-попробуем дети 7 давайте снова вернем в
-мир
-выбрать
-давайте все-таки уберем там на высоту по
-умолчанию
-вот а наш 24 она была в целях и ведь и
-сразу она правильно выставил а так
-давайте добавим следующую монетку
-должен так ой а график то не очистился
-ну можешь есть
-а где у нас здесь у нас выбор нам при
-выборе надо этого салата нам надо еще
-очищать историю мы конечно можем
-написать здесь через запятую опять же
-бонусом узнать как это работает но
-давайте все-таки сделаем вменяемо я
-здесь сделали select key
-и допишу метод ссылок ну чтобы не писать
-логику в шаблоне
-много кода в шаблоне это плохо ссылок
-trekker я говорю из равно тики и диск 1
-равно пустой массив и не забываю
-поставить запятую обновляю страницу
-5 7 до кто у нас есть биткойн кэш
-допустим эфир
-так смотрим график эфира ждем
-так интересно
-на что мы опять жалуемся мы себе вы
-видели она странно себя очень ведет
-давайте смотреть
-файлы тусич
-ум возможно мы часто прошиваем давайте
-поднимем с трех секунд до 5 но это же
-будет проблемой
-пробуем еще раз здесь итоге ты и заодно
-смотрим на консольку было ли что-то у
-нас
-хотя не очень понятно пока что это за
-файл и кто fitch на вы посмотреть так на
-чьей
-как я вечно забываю убрать этот тайм
-лайн
-чтобы он мне не мешал что я запросы ведь
-вижу вот они на той май на таймлайне
-рисуются
-так
-хром периодически обновляют dev tool и
-за это вам
-так свет мой зеркальце с тузами скажем я
-вот вижу вот над осилить он каждый раз
-выполняет запрос и так это overview
-что-то случай с тузами что ты не хочешь
-мне показывать соседи но лишь 8 0 из
-девяти request of a а галочка стоит блок
-это request
-все вот все у нас хорошо пошло да вот у
-нас идут много-много опроса
-давайте в этом графика 5 и посмотрим он
-должен
-через три секунды появится обновиться
-вот действительно эти появился первый
-элемент теперь 2 и теперь он постепенно
-будет улучшаться и вот видите работает
-наши вот эти минимальные пять процентов
-дает понять что сейчас вот на тех
-двенадцати секундах который мы смотрели
-на биткойн он вот падает вниз сильно
-и вот только что скакнул вверх ведь все
-поменялось соответственно в принципе в
-принципе первая итерация нашего подхода
-закончена
-что мы узнали сегодня сегодня мы узнали
-что с реактивностью все не так очевидны
-и почему-то вот здесь я прям оставлю
-здесь это комментариям очевидная запись
-карен тикер . прайс равно наше выражение
-вот это не заработала почему нам еще
-предстоит разобраться мы разобрали что в
-принципе тогда реактивность работает она
-работает хорошо опять же нам не пришлось
-ничего думать не шаблонах ни о чем мы
-вспомнили что витория
-когда нам не нужен когда нам нету кея за
-которого прицепиться в данных то есть
-нету уникальной составляя
-мы можем использовать яндекс мы
-вспомнили что в хоре как и везде можно
-вот здесь писать не просто переменные
-которые описаны в дата а выражение в
-данном случае у нас это вызов нашего
-метода ну и чуть чуть поигрались с
-реальным и api сходили на сервер начали
-отправлять реальные запрос и теперь нам
-предстоит
-двигаться дальше наш злобный
-тысячник ну то есть виртуальный человек
-который ставит наш этих не технические
-задания перед нами будет требовать все
-новых и новых фич и мы с вами будем их
-добавлять и смотреть во что превращается
-наш код и разговаривать что такое хорошо
-и что такое плохо
+
+Хорошо теперь пора начинать ходить за реальными данными... 
+
+>Видео посмотрите сами, я здесь привожу финальный результат:
+>
+>При добавлении новой валюты (функция **add**) запускаем таймер, который раз в 3 секунды будет запрашивать данные от АПИ. При получении данных они записываются в подходящий элемент массива (ищет по имени валюты)
+
+```js
+function add () { 
+  const newTicker = { 
+    name: ticker.value, 
+    price: '-' 
+  }
+  tickers.value.push(newTicker)
+  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()
+
+    tickers.value.find(t => t.name === newTicker.name).price = data.USD  > 1 ? data.USD.toFixed(2) : data.USD.toPrecision(2)
+  }, 3000)
+  ...
+```
+
+Хорошо самое время добавить график торговли
+
+1. Добавляем реактивную переменную _graph_
+1. В таймер получения данных добавим код для добавления значений в массив 
+
+    ```js
+    if (sel.value?.name === newTicker.name) {
+      graph.value.push(data.USD)
+    }
+    ```
+
+    Если есть выбранный тикер и его имя равно текущему тикеру, то добавляем значение в массив
+
+1. Находим в шаблоне место, где рисуется график. Удаляем ненужные дубли и добавляем цикл в одну оставшуюся полоску
+
+    ```vue
+    <div
+        v-for="(bar, idx) in normalizeGraph()"
+        :key="idx"
+        :style="{ height: `${bar}%` }"
+        class="bg-purple-800 border w-10"
+    ></div> 
+    ```
+
+    Тут сразу финальный варинант с нормализацией, про неё ниже
+
+1. Реализуем функцию нормализации, которая вычисляем минимум и максимум по всему массиву и нормализует выходные данные
+
+    ```js
+    const graph = ref([])
+
+    function normalizeGraph () {
+        const maxValue = Math.max(...graph.value)
+        const minValue = Math.min(...graph.value)
+        return graph.value.map(
+            price => 5 + ((price - minValue) * 95) / (maxValue - minValue)
+        )
+    }
+    ```
+1. При выборе другой валюты нам нужно чистить график, поэтому вместо выражения `sel = t` пишем вызов функции `select(t)` и реализуем её
+
+    ```js
+    function select (ticker) {
+        sel.value = ticker
+        graph.value = []
+    }
+    ```        
+
+Что мы узнали сегодня? Сегодня мы узнали, что:
+
+* с реактивностью все не так очевидно.
+* вспомнили что в `v-for` когда нет уникальных данных для `:key`, за которые можно прицепиться, то можно испотзовать индекс
+* вспомнили что в качестве источника данных для цикла можно использовать выражение (функцию, возвращающую массив)
+* чуть чуть поигрались с реальным api, сходили на сервер начали
+отправлять реальные запрос 
+
+Теперь нам предстоит двигаться дальше наш злобный ТЗ-шник ну то есть виртуальный человек который ставит технические задания перед нами будет требовать все новых и новых фич и мы с вами будем их добавлять и смотреть во что превращается наш код и разговаривать что такое хорошо и что такое плохо
 
 ---
 
 **Задание**
 
+Повторите практическое задание из этого занятия
 
 [Назад](./web_04.md) | [Дальше](./web_06.md)



+ 1 - 0
readme.md

@@ -340,6 +340,7 @@ https://office-menu.ru/uroki-sql Уроки SQL
 1. [Vue.js: концепции. Зачем нужен Vue.js? Структура проекта](./articles/web_02.md)
 1. [Vue.js: концепции. Реактивность. Двустороннее связывание. Декларативность.](./articles/web_03.md)
 1. [Vue.js: концепции. Бизнес логика или детали реализации? Практика (Криптономикон)](./articles/web_04.md)
+1. [Vue.js: Практика (Криптономикон)](./articles/web_05.md)
 
 <!--