Веб-приложение на node и vue, часть 1: структура проекта, api, аутентификация

Введение в Composition API

Это, безусловно, самое ожидаемое изменение в Vue3. Оно должно помочь с организацией и возможностью многократного переиспользования кода компонентов.

На данный момент, если вы работали в Vue, вы использовали то, что называется Options API. Options API организует код по свойствам: и так далее.

Несмотря на то, что это супер интуитивно понятная система, которая привлекла тысячи людей, чтобы попробовать VueJS, стало очень сложно поддерживать в рабочем состоянии компоненты больших размеров. Код для одной функции часто разбросан в нескольких местах, сотнями строк друг от друга.

Пойдем по порядку и разберемся с тем, что здесь происходит.

API Vue Composition описывает множество основных функциональных возможностей Vue, таких, как реактивность и компонентные методы. Поэтому мы должны импортировать их.

Применение является одним из самых больших изменений в Vue3. По сути, он позволяет определить, какие данные/функции передаются из компонента обратно в шаблон. Всё, что он возвращает — доступно в шаблоне.

Мы можем задавать реактивные данные, хуки жизненного цикла, вычисляемые свойства, определённые методы и возвращать всё, что захотим.

Оборачивая все эти данные методом , все эти данные автоматически становятся реактивными. Этот шаблон состояния взят из документации по .

Следует отметить, что мы объявляем переменную . Как видите, она является computed-свойством и определяется прямо в методе . Больше нет никаких отдельных вычисляемых свойств, теперь в одном месте определяются и и свойства!

Это просто определение типичных старых функций. Единственное, что тут действительно уникально, это то, что поскольку все реактивные данные хранятся в объекте состояния, мы должны сохранить его в переменную и обращаться к его своствам. Но это не специфично для Vue3 — это просто обычные объекты на Javascript.

Наконец, мы возвращаем эти данные из метода setup(). Что делает эти данные и методы доступными внутри шаблона. К счастью, код шаблона все так же сохраняет прежний формат описания.

Когда это было впервые представлено, в сообществе Vue были тонны возмущений по этому поводу, потому что люди не хотели вынужденно переделывать и переосмысливать всю свою логику компонентов. Однако, впоследствии было решено, добавить эти изменения в качестве опциональных, и люди все ещё могут использовать Options API без каких-либо препятствий.

Если вы уже хотите начать практиковаться, вы можете использовать API Vue Composition в своих проектах.

Listening to Child Components Events

As we develop our component, some features may require communicating back up to the parent. For example, we may decide to include an accessibility feature to enlarge the text of blog posts, while leaving the rest of the page its default size:

In the parent, we can support this feature by adding a data property:

Which can be used in the template to control the font size of all blog posts:

Now let’s add a button to enlarge the text right before the content of every post:

The problem is, this button doesn’t do anything:

When we click on the button, we need to communicate to the parent that it should enlarge the text of all posts. Fortunately, Vue instances provide a custom events system to solve this problem. The parent can choose to listen to any event on the child component instance with , just as we would with a native DOM event:

Then the child component can emit an event on itself by calling the built-in , passing the name of the event:

Thanks to the listener, the parent will receive the event and update value.

Когда используются компоненты без рендеринга?

Если вы когда-нибудь создавали компонент, внутри которого есть определенная логика, но хотите, чтобы пользователь этого компонента мог написать для него любой собственный HTML-код и использовать эту логику, тогда компоненты без рендеринга могут быть одним из ваших решений.

Обратите внимание, что это может быть одним из ваших решений, потому что этого также можно достичь, написав миксин или даже стандартный класс или функцию JS, которые внедряют это поведение в ваши компоненты. Фактически, можно сказать, что в большинстве случаев функциональный подход будет лучше в любом виде и в любой форме — если думать в терминах Vue 3 и API Composition, переиспользуемого и инкапсулированного кода, который можно внедрить и использовать в любом из ваших компонентов

Что касается миксинов, в частности, помните, что у них есть недостаток в виде потенциальный коллизий с другими частями вашего компонента. По сравнению с этим недостатком компоненты без рендеринга действительно выглядят более привликательными благодаря инкапсуляции логики.

Теперь, сказав это, рассмотрим сценарии, в которых вы можете решить какую либо проблему с компонентом без рендеринга просто потому, что вы хотите реализовать какое то поведение в DOM, или потому что вы пишете библиотеку компонентов, которая должна быть сверхгибкой.

В этой статье мы рассмотрим базовый пример, демонстрирующий сценарий реализации гибкого компонента. Представьте, что вы пишете компонент, который может сортировать массив объектов по определенному свойству, но вы не хотите быть строгими в отношении того, как это содержимое должно отображаться.

Возможно, пользователь захочет поместить данные компонента в <ol> или даже использовать <table>. В этом случае хорошим решением может быть компонент без рендеринга.

Что такое фреймворк

Фреймворк (framework) можно рассматривать как некий каркас для создания приложений на определенном языке программирования. Он включает в себя набор библиотек, которые позволяют значительно упростить и убыстрить разработку приложений. Также цель фреймворка – это предоставление такой среды разработки, которая позволит дорабатывать и расширять функционал проекта.

Наглядно отличие фреймворка от библиотеки можно объяснить вот так:

Фреймворк использует определенную архитектуру приложения для того, чтобы проект был разделен на логические части, модули. Например, схема разделения Model-View-Controller (MVC) подразумевает разделение на три сегмента: модель, представление и контроллер, каждый из которых можно изменять независимо от других.

Если говорить более упрощенно, то существует множество типовых задач, которые приходится решать разработчикам – и поэтому часто используются библиотеки. Использование фреймворка позволяет избежать отдельного «складирования» полезного материала где-нибудь в отдельной папке либо постоянного написания однотипного кода: фреймворк позволяет использовать встроенные классы для валидации, логирования и многих других процессов, а также имеет структуру, которую в итоге получает проект.

Фреймворки имеют массу преимуществ, именно поэтому они используются практически повсеместно. Это:

  • удобная и быстрая разработка приложения;
  • чистый код, который (чаще всего) не требует рефакторинга.

Но у использования фреймворка есть и недостатки (и забывать о них не стоит):

  • слабая защищенность из-за открытого исходного кода;
  • нужно потратить определенное время и усилия на изучение фреймворка;
  • каждый фреймворк нужно изучать отдельно (нельзя разобраться в одном фреймворке и начать понимать, как работать со всеми).

Проблемы с TypeScript в Vue

Однако, на сегодняшний день, использовать TypeScript со Vue не всегда так уж просто, вот ряд проблем с которым мы столкнулись.

Во-первых они так и не приняли мой Pull Request из-за своих же поломанных тестов =(((

Шутка, конечно же, это только моя личная боль

Два подхода

Основной проблемой TypeScript во Vue я бы назвал то, что есть два разных официальных подхода к его использованию.

Это Vue.extend (тайпинги идущие в комплекте с Vue из коробки и поддерживаемые наравне с основной библиотекой)

и очень схожий с Angular декоратор vue-class-component

Лично мне не нравится class-component, и по ряду причин мы используем Vue.extend:

  1. У class-component есть
  2. Хочется как можно меньше уходить от дефолтных ES6 Vue компонентов
  3. Необходимо, чтобы команда понимала как работает Vue без TypeScript

Другие проблемы

Вот еще некоторые проблемы с TypeScript, разной степени печальности:

  1. TSlint из коробки не работает с Vue — до сих пор нельзя запустить для .vue файлов. Вообще есть решения через fork-ts-checker, но все они некрасивые
  2. ESlint для TypeScript еще мягко говоря не супер. И plugin и parser еще в стадии разработки.
    Многие core и vue правила ломаются, но основная проблема в том, что возникают крайне непонятные ошибки.
    Однако, несмотря на это, мы используем именно его, отключив сломанные правила и подкрутив нужные.Ссылка на наш конфиг ESlint.
  3. Vuex store не типизирован снаружи, соответственно вызовы из компонента возможны фактически с любым payload

Но и Vue.extend(), в свою очередь, имеет некоторые минусы:

  1. Нельзя использовать как класс (ваш капитан), соответственно никаких приватных, статических методов и тд.
  2. Боль c мапперами из Vuex …mapGetters(), …mapState() и тд. При использовании этих мапперов теряется типизация и появляются странные ошибки. Ждем пока зальют решение
  3. Типизация data() пропертей неудобна, т.к. это функция — каждый раз приходится создавать интерфейс описывающий ее возвращаемое значение
  4. Честная типизация props вообще практически невозможна, т.к. необходимо объявлять нативный JS тип, а ожидается обычно TypeScript интерфейс, но есть некрасивое решение с кастингом

Навигация между маршрутами

Программная навигация

Программная навигация может вызываться из любого места вашего приложения таким образом:

Если мы хотим передать параметры, нам нужно использовать другой подход, основанный на использовании имен роутов.

Укажем имя роуту :

Теперь мы можем передавать параметры:

Получим ошибку «Invalid prop: type check failed for prop «id». Expected String with value «100500», got Number with value 100500».

Причина в том, что — это всегда тип данных , а мы передали программно с типом . Исправляется это просто: перечислим возможные типы данных в компоненте.

components/Board.vue

Компонент routerLink

Компонент позволяет создавать ссылки внутри сайта, которые преобразуются в «нативные» браузерные ссылки (тег ):

К таким ссылкам автоматически могут добавляться классы:

  • — точное совпадение;
  • — частичное (активен дочерний компонент указанного в атрибуте роута).

Чтобы не отображать активный класс родительских, достаточно написать атрибут :

Мы можем переопределить создаваемый элемент:

К сожалению, в таком случае, классы не проставляются.

Также можем передавать объект:

Программная проверка экземпляра компонента Vue

Как упоминалось в последнем разделе, вам может потребоваться доступ к экземплярам компонентов Vue для чтения значений, например. при написании подключаемого модуля браузера, где вам может потребоваться считывать значения или каким-то образом подключаться к ним.

Запуск обновления prop значения

Помимо выяснения того, как проверять внутренние переменные Vue, давайте также попытаемся обновить значение свойства компонента.

Скажем, у нас есть компонент, у которого есть переменная в prop, управляющая текстом элемента, как мы можем принудительно изменить значение, чтобы вызвать обновление пользовательского интерфейса?

<template>
  <h1>` msg `</h1>
</template>

<script>
export default {
  props: {
    msg: {
      type: String,
      default: ''
    }
  }
};
</script>

Поиск экземпляра компонента Vue

Для начала нам нужно найти элемент верхнего уровня компонента с помощью панели элементов Chrome devtools. В данном случае это элемент h1.

Использование команды $0

После того, как вы выбрали элемент, вы можете перейти к панели консоли в devtools и ввести $0.

$0 будет ссылкой на последний выбранный элемент на панели элементов.

Чтобы увидеть подробную информацию об экземпляре Vue, введите $0.__vue__.

Использование метода document.querySelector

Вы также можете выбрать элемент, используя любой из методов поиска DOM, таких как querySelector или getElementById и т. д. В этом случае мы будем использовать document.querySelector, чтобы увидеть экземпляр Vue:

document.querySelector('').__vue__

Здесь мы используем поиск элемента через его атрибут данных, но вы можете использовать любой допустимый селектор CSS в querySelector.

Определение значения переменной в prop

Теперь, когда у нас есть ссылка на экземпляр компонента Vue, мы можем развернуть его в консоли, чтобы увидеть, что внутри:

Добро пожаловать в Vue.js! Здесь вы можете увидеть все свойства объекта, которые Vue прикрепил к компоненту. Если вы используете какие-либо плагины, такие как Vuex или vue-i18n, вы также увидите здесь ссылку на них.

Давайте продолжим нашу задачу по обновлению значения в prop. Посмотрите внимательно, и вы увидите нашу переменную msg прямо посередине, нажмите на три точки, и вы увидите ее текущее значение.

Вы можете просмотреть значение всех свойства prop самостоятельно, используя предпочитаемую вами команду в консоли:

// Using $0
$0.__vue__.msg

// Using querySelector
document.querySelector('').__vue__.msg

Обновление значения в prop

Обновление значения в prop теперь является случаем обновления назначения переменной до желаемого значения. Так, например, используя описанную выше технику $0, вы набираете это в консоли:

$0.__vue__.msg = 'Hello from the updated value!'

И вот, вы увидите обновление пользовательского интерфейса прямо на ваших глазах!

Instance Lifecycle Hooks

Each Vue instance goes through a series of initialization steps when it’s created — for example, it needs to set up data observation, compile the template, mount the instance to the DOM, and update the DOM when data changes. Along the way, it also runs functions called lifecycle hooks, giving users the opportunity to add their own code at specific stages.

For example, the hook can be used to run code after an instance is created:

There are also other hooks which will be called at different stages of the instance’s lifecycle, such as , , and . All lifecycle hooks are called with their context pointing to the Vue instance invoking it.

Don’t use arrow functions on an options property or callback, such as or . Since an arrow function doesn’t have a , will be treated as any other variable and lexically looked up through parent scopes until found, often resulting in errors such as or .

Пользовательский интерфейс CLI Vue 3

Теперь рассмотрим пользовательский интерфейс Vue CLI. Третья версия утилиты предоставляет современный веб-интерфейс, который позволяет создавать проекты и управлять ими без использования командной строки. Чтобы запустить графический интерфейс, выполните следующую команду:

vue ui

После этого интерфейс будет доступен по адресу http://localhost:8000.

Создайте новый проект на вкладке «Create». Выберите место для его хранения, затем нажмите кнопку «+ Create a new project here».

После этого вы попадёте в интерфейс, в котором нужно указать информацию о вашем проекте.

Введите данные и нажмите кнопку «Next». Затем вы попадете на вкладку «Presets», где нужно задать варианты настройки проекта:

  • Default preset — для установки по умолчанию с плагинами Babel и ESLint.
  • Manual — для самостоятельного выбора плагинов.
  • Remote preset — для удаленной установки из репозитория Git.

Продолжим с установкой по умолчанию.

Далее нажмите на кнопку «Create Project». После этого вы попадете в новый интерфейс, который показывает прогресс создания проекта. Затем в панель управления проектом, где можно будет разместить виджеты, которые можно добавить с помощью кнопки «Customize».

Слева от панели настройки расположены ссылки на различные разделы:

  • Plugins — для добавления новых плагинов Vue CLI.
  • Dependencies — для управления пакетами.
  • Configuration — для настройки инструментов.
  • Tasks — для запуска скриптов.

Перейдите на страницу «Tasks».

Нажмите кнопку serve, а затем кнопку «Run task», чтобы запустить проект.

Остановить проект можно с помощью кнопки «Stop task».

Динамически добавляйте CSS-классы

Vue очень органично объединяет HTML и Javascript, однако мы не можем забывать и о CSS. CSS та вещь, которая делает наши приложения действительно красивыми, являясь при этом мощным инструментом.

Довольно общим паттерном в веб-приложениях является добавление и удаление классов в зависимости от состояния приложения. Мы делаем это, чтобы отключить кнопку, анимировать элементы вроде экранов загрузки и кучи других штук.

Vue предоставляет нам много способов для динамического добавления и удаления CSS-классов на основе событий приложения. Знание того, как это работает, поможет вам писать более изящный и эффективный код.

Майкл Тиссен написал статью, которая описывает все способы динамического добавления и удаления CSS-классов во Vue. Там рассматривается синтаксис массивов и объектов, использование javascript-выражений для вычисления css-классов и динамического добавления классов в пользовательских компонентах (вам не придётся добавлять свой prop!). Вы даже можете генерировать свои имена CSS-классов на лету!

Поэтапный процесс выпуска

Выпуск Vue 3.0 отмечает общую готовность фреймворка. Хотя некоторым из подпроектов фреймворка может потребоваться доработка для достижения стабильного статуса (в частности, интеграция маршрутизатора и Vuex с devtools), мы считаем целесообразным начинать новые проекты с нуля на Vue 3 уже сегодня. Мы также рекомендуем авторам библиотек начать обновление ваших проектов для поддержки Vue 3.

Ознакомьтесь с для получения подробной информации обо всех подпроектах фреймворка.

Миграция и поддержка IE11

Мы отодвинули сборку миграции (сборка v3 с поведением, совместимым с v2 + предупреждения о миграции) и сборку IE11 из-за ограничений по времени, и планируем сосредоточиться на них в четвертом квартале 2020 года. Поэтому пользователи, планирующие миграцию существующего приложения v2 или требующие поддержки IE11 должна знать об этих ограничениях в настоящее время.

Следующие шаги

В ближайшее время после релиза мы сосредоточимся на:

  • Сборка миграции
  • Поддержка IE11
  • Интерграция Router и Vuex с новым devtools
  • Дальнейшие улучшения вывода типа шаблона в Vetur

В настоящее время веб-сайт документации, ветки GitHub и теги npm dist для проектов Vue 3 будут оставаться со статусом next. Это означает, что команда npm install vue по-прежнему будет устанавливать Vue 2.x, а npm install vue@next установит Vue 3. Мы планируем к концу 2020 года переключить все ссылки на документы, ветки и теги dist на 3.0 по умолчанию.

В то же время мы начали планировать выпуск 2.7, который будет последним запланированным выпуском линейки выпусков 2.x. 2.7 будет выполнять обратный перенос совместимых улучшений из версии 3 и выдавать предупреждения об использовании API, которые были удалены/изменены в версии 3, чтобы помочь с потенциальной миграцией. Мы планируем работать над 2.7 в первом квартале 2021 года, который сразу станет LTS после выпуска с 18-месячным сроком поддержки.

Data and Methods

When a Vue instance is created, it adds all the properties found in its object to Vue’s reactivity system. When the values of those properties change, the view will “react”, updating to match the new values.

When this data changes, the view will re-render. It should be noted that properties in are only reactive if they existed when the instance was created. That means if you add a new property, like:

Then changes to will not trigger any view updates. If you know you’ll need a property later, but it starts out empty or non-existent, you’ll need to set some initial value. For example:

The only exception to this being the use of , which prevents existing properties from being changed, which also means the reactivity system can’t track changes.

In addition to data properties, Vue instances expose a number of useful instance properties and methods. These are prefixed with to differentiate them from user-defined properties. For example:

In the future, you can consult the for a full list of instance properties and methods.

Фрагменты в Vue3

Фрагменты — бескорневые компоненты, т.е. компоненты, которые в template содержат больше одного родительского элемента. В Vue2 каждый компонент должен иметь один и только один корневой элемент.
И иногда это может быть той ещё головной болью.

Есть несколько случаев, когда возврат нескольких дочерних элементов гораздо упростил бы задачу. Например, давайте возьмем пример из React и скажем, что у вас есть структура таблицы с пользовательским компонентом под названием .

Наш компонент, по задумке, должен возвращать несколько элементов <td>. Но в настоящее время компоненты Vue должны иметь один корневой элемент.

Шаблон компонента может быть похож на этот, что вызовет некоторые проблемы с разметкой.

Вот здесь Фрагменты как раз очень к стати. Они позволяют возвращать несколько элементов, не ломая при этом разметку, что делает такие задачи супер простыми.

Шаблон компонента с использованием Fragment в Vue3 может выглядеть так.

И теперь, поскольку это вернет два элемента <td>, таблица будет валидной, и это будет итоговый, желанный результат.

Это именно то, что нам и было нужно. В настоящее время существует неофициальная библиотека Vue Fragment, которая использует внутренние директивы для того, чтобы получить все дочерние элементы компонента и переместить их в нужное место.

Теперь вы можете использовать Suspense в Vue

Suspense — это функция React, которую добавили и в Vue3. Она позволяет вашему компоненту отображать временное содержимое (заглушку) до тех пор, пока ваш основной контент страницы не будет готов к отображению. Например, как часто бывает, что мы открываем страницу, и видим прелоадер, который пропадает только когда вся бизнес-логика на странице отработает.

Это полезно, когда вы хотите асинхронно загрузить содержимое в вашем методе . Смотря на код репозитория Vue-Next, кажется, что — это асинхронный метод, который возвращает Promise. Этот отлавливается компонентом , который выводит контент-заглушку до тех пор, пока основной код не будет полностью загружен и обработан.

Suspense будет полезен для:

  • Создания страниц с загрузкой
  • Ожидания ответов от API для обработки
  • Подходит для любого вида получения данных по API или асинхронной загрузки

При этом, это очень легко внедряется. Всё, что вам нужно будет сделать, это обернуть ваш код в компонент и определить ваше основное содержимое и содержимое заглушки.

Vuex — наш менеджер состояний

Vuex — это шаблон управления состоянием Vue для приложений Vue.js.

Думайте о нем как о централизованном хранилище данных или «единственном источнике правды».

Vuex действует как единое центральное хранилище для всех компонентов в одном приложении. Кроме того, отслеживает все методы (или мутации) и помогает вам управлять всеми данными в вашем веб-приложении.

Если вы используете Vue Devtools, вы можете использовать их интересные функции, такие как отслеживание или просмотр всех данных, хранящихся в Vuex.

Здесь вы увидите запущенные методы, какие данные и методы которые в данный момент хранятся в хранилище Vuex, и сможете вернуться, чтобы проследить ваши шаги, изменить текущие данные и т. д.

Хотя веб-приложение несколько усложняется, добавлением накладных расходов, оно очень помогает разделить всю логику в один файл, предоставляя доступ к нескольким независимым компонентам и многому другому.

Давайте посмотрим, как я использовал его в реальной обстановке:

Снова довольно просто. Мы загружаем все функции и данные в файл store.js, который станет нашим «Единственным источником правды». Затем для каждого необходимого компонента мы загрузим нужные нам части.

Используйте vue-router для роутинга на клиенте

Если вы осуществляете роутинг на клиенте, то написать своё решение в целом не сложно. На самом деле это просто — сопоставить маршруты и поменять после этого компоненты.

Однако использование ещё проще! К тому же, это официальный пакет Vue, поэтому вы можете не беспокоиться по поводу совместимости и поддержки.

И как только вы начнёте работать с:

  • запросами
  • параметрами маршрута
  • вложенными маршрутами
  • динамическим сопоставлением маршрутов
  • транзишенами

…а вы, скорее всего, начнёте с этим работать, то написание своего решения станет слишком сложным, громоздким. Поэтому вместо этого читайте гайд по vue-router от Эда Зынды «Начало работы с Vue Router».

DOM Template Parsing Caveats

Some HTML elements, such as , , and have restrictions on what elements can appear inside them, and some elements such as , , and can only appear inside certain other elements.

This will lead to issues when using components with elements that have such restrictions. For example:

The custom component will be hoisted out as invalid content, causing errors in the eventual rendered output. Fortunately, the special attribute offers a workaround:

It should be noted that this limitation does not apply if you are using string templates from one of the following sources:

  • String templates (e.g. )
  • Single-file () components

That’s all you need to know about DOM template parsing caveats for now – and actually, the end of Vue’s Essentials. Congratulations! There’s still more to learn, but first, we recommend taking a break to play with Vue yourself and build something fun.

Once you feel comfortable with the knowledge you’ve just digested, we recommend coming back to read the full guide on Dynamic & Async Components, as well as the other pages in the Components In-Depth section of the sidebar.

##company## — ##description##

Edit this on GitHub!

Netlify

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector