|
|
@@ -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_)"
|
|
|
|
|
|

|
|
|
|
|
|
@@ -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`
|
|
|
-* научились добавлять элементики, удалять, передавать в
|
|
|
+* научились добавлять элементы, удалять, передавать в
|
|
|
обработчике события аргументы
|
|
|
|
|
|
---
|
|
|
|
|
|
-**Задание**
|
|
|
+## Задание
|
|
|
|
|
|
Повторите практическое задание (Криптономикон)
|
|
|
|