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

Нет интернета - нет проблем

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

Интернет - это здорово, но только если у вас есть к нему доступ. Если вы не можете этого сделать, пользователь не должен быть навсегда лишен его услуг. Один из способов решить эту проблему - использовать хранилище на стороне клиента.

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

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

Что мы будем делать

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

Клиентские параметры

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

LocalStorage

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

IndexedDB

Если вы хотите хранить более сложные данные, файлы или даже большие двоичные объекты в браузере, IndexedDB - это то, что вам нужно. Это также база данных, которая вам понадобится при создании PWA.

IndexedDB - это система баз данных на основе транзакций, которая описывается MDN как объектно-ориентированная база данных на основе JavaScript. Это означает, что данные хранятся не в таблице со строками и столбцами, как в СУБД на основе SQL, а в объектах JavaScript, которые доступны / индексируются с помощью ключа.

Подробнее на MDN

Я также написал еще одну статью, в которой мы реализуем IndexedDB.



Для нашего приложения ToDo LocalStorage более чем достаточно, поэтому давайте его реализуем.

Настраивать

Если вы хотите следовать инструкциям, git clone, чтобы начать работу, соответствующую ветку списка дел.

$ git clone -b formReuse --single-branch https://github.com/MaxMonteil/VueTodo.git

Окончательный проект находится по адресу:

$ git clone -b localStorage --single-branch https://github.com/MaxMonteil/VueTodo.git

Добавление LocalStorage

На самом деле добавить localStorage в наше приложение для задач невероятно просто и выполняется в два этапа.

Первый шаг - проверить localStorage на наличие уже существующих данных, которыми можно заполнить наш компонент (он же Read), второй шаг - сохранить состояние наших задач в localStorage (он же Write).

Для этого мы будем использовать два метода, предлагаемых localStorage API, getItem и setItem.

Чтение из хранилища

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

Там мы проверяем, есть ли в localStorage значения, связанные с ключами «todos» и «completed», имеет смысл использовать имена ключей, как мы это делаем в данных наших компонентов. Фактически мы можем пойти дальше и иметь дополнительное значение с именем dataFields, которое будет содержать имя любых будущих значений, которые мы хотели бы сохранить на клиенте.

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

Также следует иметь в виду, что localStorage принимает только строковые значения, для массивов и объектов нам необходимо преобразовать данные в JSON и обратно.

Запись в хранилище

Сохранить наши задачи так же просто.

Мы создадим метод saveTodos, который будет обрабатывать наш полезный массив dataFields, преобразовывать данные в строки и сохранять их.

А как насчет правок?

Чтобы знать, что задача была отредактирована, нам также необходимо создать событие из компонента ListItem и прослушать его в TodoList.

При этом все, что нам нужно сделать, это вызывать метод всякий раз, когда мы добавляем, удаляем, редактируем или завершаем задачу!

Двигаясь дальше

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

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

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

Refactor refactor refactor

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

Добавьте vuex в приложение с помощью

$ vue add vuex

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

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

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

Абстрактные абстрактные абстрактные

Следующий шаг - уменьшить нашу зависимость от LocalStorage или, по крайней мере, сделать как можно более безболезненным изменение или даже отказ от него.

Для этого создадим папку api/ с файлом localStorageService.js. Там мы делаем все вызовы localStorage из магазина.

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

Вы можете получить код для этого в этой ветке:

$ git clone -b vuexRefactor--single-branch https://github.com/MaxMonteil/VueTodo.git

Заключение

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

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

Надеюсь, это помогло вам в ваших собственных проектах.