Евгений Колесников 2 месяцев назад
Родитель
Сommit
bfeae5cd7e
1 измененных файлов с 62 добавлено и 50 удалено
  1. 62 50
      articles/web_04.md

+ 62 - 50
articles/web_04.md

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