Во вью реализован компонентный подход для реализации приложения
Так же вью решает проблему реактивности в веб-приложениях. При обычном подходе, страница не знает, что у неё изменилось значение какого-либо элемента
При использовании вью, мы создаём модели, которые представляют собой данные, которые мы можем изменять в шаблонах
Те данные, которые мы описываем под изменения, называются моделями. Под капотом они оборачиваются в прокси, который срабатывает на получение и установку модели и тем самым срабатывает рендер
Начало разработки. Создание проекта
Устанавливаем CLI от Vue и создаём с его помощью проект
И таким образом будет выглядеть стоковый проект
Компонент App
В основном файле JS мы подключаем корневой компонент, в который и будут складываться все компоненты
src > main.js
И таким образом выглядит стоковый компонент vue:
template - шаблон компонента
script - скрипты компонента
style - стили компонента
src > components > App.vue
Интерполяция
Внутрь двойных скобок {{ переменная }} мы можем помещать переменные из this скоупа
src > components > App.vue
Methods. V-ON. Слушатели событий
Из скрипта мы можем экспортировать методы, которые мы будем использовать внутри событий вёрстки. Чтобы подключить события вью, мы можем воспользоваться конструкцией v-on: или его аналогом @
src > components > App.vue
Vue devtools. Инструменты разработчика
Cтили
Флаг scoped говорит нам о том, что стили будут сохраняться в одном компоненте и не будут уходить в глобалку
Отрисовка в цикле. Директива V-FOR
Для создания итерируемой конструкции для перебора имеющихся данных во вью существует две директивы:
v-for - в ней мы указываем, перебор какого массива будет
v-bind:key - присваиваем ключ для каждого элемента перебора
Двустороннее связывание
Для реализации добавления поста на страницу, нужно сначала реализовать двусторонне связывание, которое позволит синхронизировать данные из инпутов с данными компонента
Конкретно для связывания данных во вью используется v-bind, который привязывает одни данные под другие
И так же нам нужен будет атрибут @input, который хранит в себе метод присвоения определённых данных из формы на странице к форме вью (он будет передавать наши введённые данные в данные компонента)
Так же можно сократить запись и вместо отдельного метода просто указать, что мы приравниваем нужное нам значение к зарезервированному ивенту $event.target.value
Модификаторы stop, prevent
Далее реализуем метод createPost, через который будем добавлять новые посты. Но тут встаёт проблема, что страница перезагружается при отправке формы.
Чтобы исправить вышеописанную проблему, можно передать в функцию event и прописать stopPropagation или preventDefault, но вью предоставляет модификатор @submit, который в себе имеет prevent, останавливающий выполнение ивентов при сабмите формы
Декомпозиция. Создаем переиспользуемые компоненты. Props. Передаем данные в компонент
Первым делом вынесем список постов. Он должен будет извне принимать список постов. Чтобы указать принимаемые пропсы в компонент, нужно указать внутрь props нужное значение, прописать его типы и указать обязателен ли этот пропс
PostList.vue
Компонент формы, который пока не может создавать новые посты
PostForm.vue
И теперь, чтобы подключить дочерние компоненты в целевой, нужно:
Импортировать нужные компоненты в скриптах
Проинициализировать их в блоке components
Добавить их в в сам компонент в темплейте
Чтобы передать пропсы внутрь компонента, нужно через v-bind прописать те пропсы, которые принимает компонент и указать объект с пропсами.
Так же, чтобы кратко записать биндинг достаточно написать вместо v-bind просто “:”
App.vue
Пропсы изменять в дочернем компоненте нельзя. Нужно их изменять в родительском и передавать в готовом виде уже в дочерний!
V-MODEL
Стандартное двусторонне связывание предусматривает под собой написание правильных событий и атрибутов и постоянное повторение данной записи.
Можно упростить связывание через указание простого атрибута v-model, который за нас реализует указание правильных событий, атрибутов, функций присвоения значений.
Так же далее создадим заново функцию создания поста.
Сейчас перед нами встаёт задача передачи данных для создания нового поста в компонент со списком постов
PostList.vue
$emit. Обмен данными между дочерним и родительским компонентом
Передать данные от ребёнка к родителю напрямую - не получится. Чтобы совершить данное действие придётся воспользоваться событием, на которое нужно будет подписать родителя, чтобы тот получил данные из ребёнка.
Для этого нужно будет воспользоваться $emit. В него мы передаём название события первым аргументом, а последующими передаём данные, которые попадут в функцию, которая будет подписана на данное событие
В форме постов мы создаём метод createPost внутри которого эмитим ивент, в который передаём новый пост, а так же ещё несколько пропсов для примера.
PostForm.vue
Чтобы воспользоваться ивентом, нужно:
На компонент, который эмитит событие, нужно навесить атрибут @имя_события = функция_которая_примет_пропсы
В родительском компоненте создаём метод, который уже из описанного в темплейте события будет принимать пропсы
App.vue
И далее стоит разбить пост в отдельный компонент, а список постов в другой
PostItem.vue
PostList.vue
Библиотека UI компонентов
Если мы хотим создать компонент, внутрь которого можно будет поместить какой-либо текст, то нам нужно будет вложить в него тег slot, который означает, что все вложенные внутрь компонента элементы будут помещаться в данном месте
components > ui > UiButton.vue
Так же нужно упомянуть, что все стили и классы, которые мы помещаем в компонент, применяются на корневой элемент внутри компонента
Глобальная регистрация компонента
Чтобы не импортировать каждый раз компонент UI в другие компоненты, можно глобально зарегистрировать компонент
Для этого нужно сначала дать имя самому компоненту
`components > ui > UiButton.vue
Далее нужно экспортировать массив компонентов
components > ui > index.js
И уже затем нужно глобально к приложению эти компоненты подцепить через итерацию массива
src > main.js
И теперь можно спокойно использовать компонент в приложении без импорта его во все файлы
Подробно о V-MODEL
Во второй версии Vue на весь компонент распространялся только один v-model. В третьей версии мы можем указать конкретно к чему мы хотим указать двусторонне связывание. Однако, если мы не укажем с чем мы хотим связать значения, то по умолчанию связывание будет с пропсом modelValue компонента
Чтобы реализовать связывание по стандартному modelValue без указания конкретного значения через атрибут, мы можем написать такой код и сбиндить значение инпута со значением модели через событие, которое будет срабатывать на update
components > ui > UiInput.vue
Если мы хотим своё кастомное значение, то мы можем указать своё кастомное значение для связывания нашего кастомного компонента инпута
`components > ui > UiInput.vue
И при указании модели, нужно будет дополнить связывание атрибутом value
Удаление поста. Ключи KEY в цикле
Чтобы реализовать возможность удаления поста, нам нужно заэмиттить событие, которое будет возвращать пост наверх из самого элемента поста по клику на кнопку удаления поста
PostItem.vue
И далее мы принимаем из события remove пост и заново его передаём вверх
PostList.vue
Теперь мы можем в родительском компоненте затриггерить функцию удаления поста, в которую сразу попадёт пропс с постом и позволит отрисовать новый массив постов без поста с определённым id
App.vue
Отрисовка по условию
Для отрисовки определённых блоков по условию у нас есть три разных атрибута:
v-if - отрендерит, если условие будет удовлетворено
v-else-if
v-else - отрендерит, если прошлое условие не будет удовлетворено
Эти атрибуты вставляют нужный код, если он будет соответствовать условию.
PostList.vue
Так же у нас есть атрибут, который просто скрывает элемент, если он не соответствует условию - v-show
PostList.vue
Модальное окно
Само модальное окно. Мы его отображаем, если пропс show будет true. Скрывать модальное окно мы будем через поднятие состояния вверх через эмиттер.
components > ui > ModalWindow.vue
В родительском компоненте отображать модалку будем через использование функции showDialog и пропса show, который двусторонне связываем и передаём локальное значение dialogVisible
App.vue
Модификаторы V-MODEL
Модификаторы добавляются через точку и модифицируют конечную функциональность v-model.trim.number. trim срезает пробелы, а number переводит значение сразу к числу
App.vue
Работа с сервером. Получаем посты. Axios
Добавляем метод fetchPosts, который будет срабатывать при нажатии кнопки. Все полученные данные с сервера будут сразу заноситься в свойство posts
App.vue
Жизненный цикл компонента
У нас есть достаточное количество различных хуков, которые работают на протяжении всего цикла существования vue-компонента:
beforeCreate - вызывается перед созданием компонента. То есть тут ещё не инициализировались события и жизненный цикл
created - тут уже стоит вызывать условия на проверки и что-то инициализировать. В этот момент в компонент добавляются инъекции и реактивность
beforeMount - отрабатывает до того, как элемент встроится в дом-дерево
mounted - отработает после встраивания
beforeUpdate - до обновления
updated - выполняется после обновления компонента
beforeDestroy - до уничтожения компонента
destroyed - после его уничтожения из дом-дерева
Индикатор загрузки данных
Первым делом нужно вызывать загрузку постов в хуке mounted, который при монтировке компонента подгрузит нужные данные
Далее зададим поле isPostsLoading, которое будем менять внутри функции fetchPosts. Данное поле будет использоваться для условия отображения
App.vue
Выпадающий список. Сортировка постов
Наблюдаемые WATCH и вычисляемые COMPUTED свойства
Анимации transition group
Поиск постов. Фильтрация
Пагинация. Постраничный вывод
Динамический биндинг классов и стилей
Динамическая пагинация. Бесконечная лента. Intersection API
Refs. Доступ к DOM элементу
VUE-ROUTER. Постраничная навигация
Динамическая навигация
Создаем собственные директивы V-INTERSACTION и V-FOCUS