Евгений Колесников 2 kuukautta sitten
vanhempi
sitoutus
bfeae5cd7e
1 muutettua tiedostoa jossa 62 lisäystä ja 50 poistoa
  1. 62 50
      articles/web_04.md

+ 62 - 50
articles/web_04.md

@@ -34,7 +34,13 @@
 
 **Расшифровка скринкаста** (вольный пересказ своими словами)
 
->**Внимание**, сегодня мы с вами напишем очень и очень плохой код почему так и зачем мы это сделаем мы это сделаем потому что когда вас учат писать сразу хороший код вас учат решать задачу одним способом рано или поздно вы сталкиваетесь задач и решения которые вы не знаете и оказываетесь ситуации когда не понимаете хорошие ваше решение или плохое мы с вами вначале напишем плохой но к сожалению распространенный код и шаг за шагом в рамках этой серии видео будем его улучшать у нас как и в реальной жизни будут появляться новые требования заказчика мы будем находить какие-то баги сами уже у себя и сами героический фиксить и так далее таким образом на выходе вы не только получите хороший код для решения этой задачи но и понимание как глядя на код понять что он действительно плохой 
+**Внимание**! Cегодня мы с вами __напишем очень и очень плохой код__ почему так и зачем мы это сделаем? 
+
+Мы это сделаем потому что когда вас учат писать сразу хороший код, вас учат решать задачу одним способом. Рано или поздно вы сталкиваетесь c задачами, решения которые вы не знаете и оказываетесь ситуации когда не понимаете хорошее ваше решение или плохое. 
+
+Мы с вами вначале напишем плохой, но к сожалению распространенный код и шаг за шагом, в рамках этой серии видео, будем его улучшать. У нас, как и в реальной жизни, будут появляться новые требования заказчика, мы будем находить какие-то баги сами уже у себя и сами героический фиксить и так далее. 
+
+Таким образом, на выходе вы не только получите хороший код для решения этой задачи, но и понимание как глядя на код понять что он действительно плохой.
 
 >В рамках расшифровки скринкаста я сразу буду переписывать его на Vue3, используя `vite` + `script setup`
 
@@ -42,26 +48,27 @@
 
 Чем же мы с вами займемся? Мы с вами напишем небольшое приложение, которое позволяет добавлять в список отслеживания криптовалюты, используя **api** `cryptocompare.com`.
 
-Соответственно мы будем иметь возможность добавить криптовалютные пары "имя валюты - USD" в наблюдение и, когда мы выбираем конкретную валюту, у нас внизу появляется график отслеживания. Мы можем убрать выбрать другую пару и вот сейчас постепенно шаг обновления 1 5 секунд у нас будут появляться собственно данные о изменение вот соответственно график автоматически адаптируется под минимальные и максимальные значения поэтому в начале он может выглядеть странно но со временем он нормализуется. 
-
-График нам не очень интересно всем мы можем что-то удалить мы можем добавить криптовалюту мы можем так далее ну и когда мы обновляем страницу у нас очевидно встречает пустой экран вот мы добавляем в начале черточка когда нету данных и потом когда данные приезжают кто у нас там еще есть bitcoin кэш допустим у нас будут вот обновляться что у нас есть на входе на входе дизайнер нам выдал вот такой вот завершены html с него мы и будем начинать и он и ставит станет нашей отправной точкой 
+Соответственно мы будем иметь возможность добавить криптовалютные пары "имя валюты - USD" в наблюдение и, когда мы выбираем конкретную валюту, у нас внизу появляется график отслеживания. 
 
 ### Создание нового проекта, удаление лишего
 
 В домашнем задании [первой лекции](./web_01.md) вы должны были научится создавать приложене **Vue**. Откроем его и удаляем "рыбу": 
 
-* нам не нужны директории `src/assets` и `src/components` (весь код пока будем писать в `App.vue`)
+* нам не нужно содержимое директорий `src/assets` и `src/components`
 * в `App.vue` удаляем всё из скрипта и шаблона (стили вообще удаляем)
 
-    ```vue
-    <script setup>
-    </script>
-
+    ```html
     <template>
-    empty
+    <!-- тут будет html -->
     </template>
     ```
 
+    ```js
+    <script setup>
+    // тут будет бизнес-логика (js)
+    </script>
+    ```
+
 * в `main.js` комментируем строчку с импортом `./main.css`
 
 Можем запустить проект командой `npm run dev` и посмотреть на пустое окно, убедившись заодно, что нет ошибок
@@ -70,7 +77,7 @@
 
 В [материалах](#материалы-к-заданию) есть ссылка на файлы с вёрсткой. 
 
-1. Скопируйте содержимое `<body>` из файла `index.htm` в ваш шаблон (внутрь тега `<template>` вместо слова **empty**)
+1. Скопируйте содержимое `<body>` из файла `index.htm` в ваш шаблон (внутрь тега `<template>` вместо комментария)
 
     Все сработало. Как видите все подключилось но выглядит как-то криво 
     
@@ -92,15 +99,15 @@
 
 ### Начинаем работу с App.vue
 
-Сегодня все наше внимание будет приковано к файлику `App.vue`. 
+Сегодня все наше внимание будет приковано к файлу `App.vue`. 
 
 Итак, что нам надо? Будем двигаться сверху вниз, оживляя эту страницу. Первое что нам надо это научиться заполнять поле "Тикер" и, когда нажимается кнопка "добавить", реагировать на нажатие.
 
-Как мы помним, сильной стороной **Vue** является так называемое **двухстороннее связывание**, когда мы можем определить что-то в данных java-скрипта и вывести это что-то на экран. И когда что-то на экране поменяется оно автоматически изменится в приложении. 
+Как мы помним, сильной стороной **Vue** является так называемое **двухстороннее связывание**, когда мы можем определить _что-то_ в данных java-скрипта и вывести это _что-то_ на экран. И когда _что-то_ на экране поменяется оно автоматически изменится в приложении. 
 
-Ну что же давайте учиться это делать. Как вы помните **vue** декларативен. Что это означает? Это означает, что нам надо будет выучить по сути язык описания компонентов, благо он не сложный. То есть у нас есть несколько заранее зарезервированных слов, с помощью которых мы будем объявлять те или иные не побоюсь этого слова особенности компонент.
+Ну что же давайте учиться это делать. Как вы помните **vue** декларативен. Что это означает? Это означает, что нам надо будет выучить язык описания компонентов, благо он не сложный. То есть у нас есть несколько заранее зарезервированных слов, с помощью которых мы будем объявлять те или иные особенности компонент.
 
->Дальше в скринкасте расписывается функция `data()`, которая возвращает реактивные данные, доступные в шаблоне. Но это устаревший синтаксис `Option API` из **Vue2**, во **Vue3** стандартом является `Setup API`, причем имеющий два варианта написания: функция `setup()` и `script setup`. Мы будем использовать `<script setup>`.
+>Дальше в скринкасте расписывается функция `data()`, которая возвращает реактивные данные, доступные в шаблоне. Но это устаревший синтаксис __Option API__ из **Vue2**, во **Vue3** стандартом является `Setup API`, причем имеющий два варианта написания: функция `setup()` и `script setup`. Мы будем использовать `<script setup>`.
 
 Просто определим [реактивную](https://ru.vuejs.org/guide/essentials/reactivity-fundamentals.html) переменную:
 
@@ -108,9 +115,11 @@
 const ticker = ref('default')
 ```
 
-Задав ей значение по умолчанию (`'default'`) просто чтобы мы увидели как же осуществляется "двухстороннее связывание". Как вы помните, **vue** это **html-first** фреймворк, это означает что мы пишем html, а дальше с помощью специальных атрибутов и интерполяций подсказываем как связать наш html с данными и первый атрибут (все атрибуты которые используют **vue** начинаются c `v-`) это `v-model`.
+Задав ей значение по умолчанию (`'default'`) просто чтобы мы увидели как же осуществляется "двухстороннее связывание". 
 
-`v-model` как раз говорит "свяжи мне в две стороны вот этот вот input с данными (переменной _ticker_)"
+Как вы помните, **vue** это **html-first** фреймворк, это означает что мы пишем html, а дальше с помощью специальных атрибутов и интерполяций подсказываем как связать наш html с данными и первый атрибут (все атрибуты которые используют **vue** начинаются c `v-`) это `v-model`.
+
+`v-model` как раз говорит "свяжи мне в две стороны вот этот вот __input__ с данными (переменной _ticker_)"
 
 ![](../img/web_011.png)
 
@@ -120,7 +129,9 @@ const ticker = ref('default')
 
 #### [Интерполяция](https://ru.vuejs.org/guide/essentials/template-syntax.html#text-interpolation)
 
-Мы используем так называемый синтаксис интерполяции...  это вот такие две фигурные скобки. Обратите внимание их можно использовать только в тех местах где вы вводите текст просто на странице. То есть я не могу его использовать где-то внутри атрибута, только там где просто обычный текст. И я пишу точно также `ticker` и смотрите видите вот она магически обновляется мы научились с вами связывать переменные в две стороны это работает c инпутами, чекбоксами, с радио батонами. Потом мы научимся писать наши собственные компоненты которые умеют работать с `v-model` 
+Мы используем так называемый синтаксис интерполяции...  это две фигурные скобки. Обратите внимание их можно использовать только в тех местах где вы вводите текст просто на странице. То есть я не могу его использовать где-то внутри атрибута, только там где просто обычный текст. 
+
+Например:
 
 ```vue
 <label 
@@ -134,22 +145,25 @@ const ticker = ref('default')
 </label>    
 ```
 
-Давайте что-нибудь с этим сделаем а что мы можем с этим сделать? мы теперь знаем как выводить как же вот я нажимаю "добавить" я хочу чтобы что-то произошло.
+Теперб, если начать менять содержимое поля ввода __input__, то будет меняться и содержимое метки (__label__)
+
+Мы научились с вами связывать переменные в две стороны. Это работает c инпутами, чекбоксами, с радио батонами. Потом мы научимся писать наши собственные компоненты которые умеют работать с `v-model` 
 
-Как бы мы это делали в обычном java-скрипте? Мы нашли бы элемент на страничке через query-селектор, добавили слушатель на события клик и после этого сказали бы
-какую функцию вызывать.
+Давайте что-нибудь с этим сделаем а что мы можем с этим сделать? Например при нажатии кнопки "добавить" я хочу чтобы что-то произошло.
 
-Во вью все работает похожим образом. Мы пишем `v-on:click="..."` (мы говорили что все атрибуты **vue** начинаются с `v-`), дальше имя события клик. Мы здесь можем написать к примеру обычный java-скрипт код (`"ticker = 123"`) и смотрите нажимаю кнопку "добавить", видите в переменную `ticker` записалась значение `123` и она автоматически изменилась.
+Как бы мы это делали в обычном java-скрипте? Мы нашли бы элемент на страничке через query-селектор, добавили слушатель на события клик и после этого сказали бы какую функцию вызывать.
 
-Но согласитесь писать код прямо в верстке как то супер странно, поэтому мы хотим чтобы код можно было писать рядом с вёрсткой (вспоминаем про **SFC**)
+Во __VUE__ все работает похожим образом. Мы пишем `v-on:click="..."` (мы говорили что все атрибуты **VUE** начинаются с `v-`), дальше имя события клик. Мы здесь можем написать обычный java-скрипт код (например, `"ticker = 123"`). И при нажатии кнопку "добавить" в переменную `ticker` запишется значение `123` и верстка автоматически изменилась (поменялось содержимое поля ввода и метки).
+
+Но согласитесь писать код прямо в верстке как то странно, поэтому мы хотим чтобы код можно было писать рядом с вёрсткой (вспоминаем про **SFC**)
 
 >В оригинальном видео рассказывается про ключевое слово `method`, но это тоже устаревший синтаксис.
 
-Мы просто в `<script setup>` пишем функцию (напомню, что в шаблоне видны все имена, описанные в скрипте, а название функции это тоже имя)
+Мы просто в `<script setup>` пишем функцию (напомню, что в секции `<template>` видны все имена, описанные в скрипте, а название функции это тоже имя)
 
 ```js
 <script setup>
-import { ref } from "vue";
+import { ref } from "vue"
 
 const ticker = ref('default')
 
@@ -159,13 +173,13 @@ function add () {
 </script>
 ```
 
-Обратите внимание здесь можно будет потом передавать аргументы, то есть в 99% случаях надпись `add` и `add()` абсолютно одинаковы, то есть если **vue** видит надпись, что при событий клик вызов функции `add`, он понимает что это функцию надо вызвать а если он видит вот так `add()` "о, это же выражение я вот беру и вызываю функцию add".
+Обратите внимание здесь можно будет потом передавать аргументы, то есть в 99% случаях надпись `add` и `add()` абсолютно одинаковы.
 
 Итак пробуем: выводится алерт
 
 Хорошо, но нам же хочется в скрипте дотянуться до значения, введенного в input. Как же нам это делать?
 
->...`this` используется только во **Vue2**, во **Vue3** используется ЗНАЧЕНИЕ реактивной переменной
+>...`this` используется только во **Vue2**, во **Vue3** используется ЗНАЧЕНИЕ (поле `value`) реактивной переменной
 
 ```js
 function add () {
@@ -184,7 +198,7 @@ function add () {
     ...
 ```
 
-Дальше реализуем список тикеров. Очевидно что нам надо как-то научиться повторять какие-то вещи. Очевидно что повторять нам надо что то, что то это скорее всего будет массивом.
+Дальше реализуем список тикеров. Очевидно что нам надо как-то научиться повторять какие-то вещи. Очевидно что повторять нам надо что то, то это скорее всего будет массивом.
 
 Создадим в скрипте массив тикеров: просто объявляем переменную
 
@@ -196,12 +210,9 @@ const tickers = ref([1, 2, 3, 4])
 
 Как сказать **vue** "повтори какую-то вещь несколько раз"?
 
-Во-первых, что за вещь мне надо повторять? Нужно в верстке найтие место, которое повторяется, удалить лишние повторы и использовать так называемую структурную директиву (директивами называются атрибуты которые обрабатываются **vue** опять же существенное упрощение но пока сойдет и так) `v-for`. У нас есть две ключевые структурные
-директивы мы потом поговорим почему они являются структурными но пока запомнить `v-for` и `v-if` они настолько суровы что даже друг с другом не дружат.
-
-`v-for` работает точно также как цикл `for of` (или `for in`)...
+Во-первых, что за вещь мне надо повторять? Нужно в верстке найти место, которое повторяется, удалить лишние повторы и использовать так называемую структурную директиву (директивами называются атрибуты которые обрабатываются **vue** опять же существенное упрощение но пока сойдет и так) `v-for`. У нас есть две ключевые структурные директивы мы потом поговорим почему они являются структурными но пока запомнить `v-for` и `v-if` они настолько суровы что даже друг с другом не дружат.
 
-```vue
+```html
 <div
     v-for="t in tickers"
     v-bind:key="t"
@@ -214,7 +225,7 @@ const tickers = ref([1, 2, 3, 4])
 
 Для циклов нужно использовать констукцию `v-bind:key="уникальное значение"`. В нашем случае мы можем использовать просто значение `t`, но есть синтаксис `v-for` c индексом:
 
-```vue
+```html
 <div
     v-for="(t, index) in tickers"
     v-bind:key="index"
@@ -231,13 +242,11 @@ const tickers = ref([1, 2, 3, 4])
 
 Давайте чуть-чуть доведем до ума, но перед этим сделаем маленький шаг назад дело в том что в мире **vue** огромное количество раз вы будете писать в `v-bind` и `v-on`.
 
-Писать вот так очень многословно поэтому придумали так называемую короткую запись отдельные люди называют их ярлыками, когда вместо `v-on` мы пишем собаку `@`, а вместо `v-bind` просто ничего не пишут, оставляют только  `:`.
+Писать так очень многословно поэтому придумали так называемую короткую запись, когда вместо `v-on` мы пишем собаку `@`, а вместо `v-bind` просто ничего не пишут, оставляют только  `:`.
 
-Хорошо уже похоже на правду давайте мы сделаем еще что-то а что ещё нам же надо выводить у нас тут какой-то глупый массив только со строками. 
+Нам надо выводить будет явное имя валюты и значение соответственно наш массив нужно переопределить как то так:
 
-Нам надо выводить будет явное имя валюты и значение соответственно наш массив будет выглядеть как то так:
-
-```vue
+```js
 const tickers = ref([
     { name: 'DEMO', price: '-' },
     { name: 'DEMO', price: '-' },
@@ -249,7 +258,7 @@ const tickers = ref([
 
 Видите, теперь он начал выводить переменную `t` которая содержит весь объект и радостно нарисовал строковое представление объекта. Нам надо вывести поля `name` и `price`:
 
-```vue
+```js
 <dt class="text-sm font-medium text-gray-500 truncate">
     {{ t.name }}
 </dt>
@@ -260,9 +269,9 @@ const tickers = ref([
 
 #### Добавление элементов
 
-Давайте научимся для начала добавлять такие элементы плюс давайте приведем это всё в тот дизайн который был а именно добавим `USD` в пару:
+Давайте научимся для начала добавлять такие элементы плюс давайте приведем это всё в тот дизайн который был, а именно добавим `USD` в пару:
 
-```vue
+```js
 <dt class="text-sm font-medium text-gray-500 truncate">
     {{ t.name }} - USD  
 </dt>
@@ -295,7 +304,7 @@ function add () {
 }
 ```
 
-Теперь хочется очищать тикер когда он добавился в массив. Вспомним что у нас связь и двухсторонняя и просто запишем в тикер пустую строку нажимаем "добавить" и вот все испарилось
+Теперь хочется очищать тикер когда он добавился в массив. Вспомним что у нас связь двухсторонняя и просто запишем в тикер пустую строку в методе _add_
 
 ```js
 function add () { 
@@ -304,23 +313,26 @@ function add () {
       price: '-' 
     }
     tickers.value.push(newTicker)
+
+    // очищаем текущее значение
     ticker.value = ''
 }
 ```
 
-Обратите внимание это фундаментальный акцент на том как вообще работает **vue** мы хотим и умеем работать с данными html декларативно мы же теперь с вами знаем это слово описываем как к этим данным привязываемся мы никогда не меняем html напрямую 
+Обратите внимание это фундаментальный акцент на том как вообще работает **vue**. Мы хотим и умеем работать с данными html декларативно (мы же теперь с вами знаем это слово). Описываем как к этим данным привязать переменные и никогда не меняем html напрямую 
 
 #### Удаление пар
 
-Хорошо давайте двигаться дальше мы берем и хотим удалять прекрасно давайте найдем эту кнопочку удалить вот она мы с вами уже знаем что мы вешаем события клик и назовем `handleDelete` а теперь смотрите если мы вот так напишем как мы поймем какой элемент надо удалять да черт его знает она же просто клонируется и все эти кнопочки будут вызывать один и тот же метод. очевидно нам надо как-то передать туда параметры помните рассказал что там скобочки и без скобочек это одно и то же. а почему да потому что мы здесь можем писать java-script поэтому мы можем написать `@click="handleDelete(t)"
+Хорошо давайте двигаться дальше - теперь мы хотим удалять валюты. Прекрасно давайте найдем эту кнопку удалить, повесим на нее событие __click__ и назовем `handleDelete`:
 
-```vue
+
+```html
 <button
     @click="handleDelete(t)"
     ^^^^^^^^^^^^^^^^^^^^^^^^
 ```
 
-"Пожалуйста удали наш тикер, который лежит в массиве tickers". Звучит круто ну что давайте напишем этот `handleDelete`  
+Давайте напишем метод `handleDelete` (просто фильтруем исходный массив, возвращая все элементы, кроме того, который хотим удалить)
 
 ```js
 function handleDelete (tickerToRemove) {
@@ -342,7 +354,7 @@ function handleDelete (tickerToRemove) {
 1. Добавляем структурный атрибут `v-if`
 1. Если хотим скрыть несколько не вложенных тегов, то можем завернуть их в тег `template`
 
-```vue
+```html
 <template
     v-if="tickers.length > 0">   
 ```
@@ -357,12 +369,12 @@ function handleDelete (tickerToRemove) {
 * научились подписываться на события через `v-on` или краткую запись `@`
 * научились выводить данные в шаблон через скобочки то что называется интерполяцией
 * научились двум ключевым структурным директивам `v-for` и `v-if`
-* научились добавлять элементики, удалять, передавать в
+* научились добавлять элементы, удалять, передавать в
 обработчике события аргументы
 
 ---
 
-**Задание**
+## Задание
 
 Повторите практическое задание (Криптономикон)