Изменения внутри массива
Приложение кафе должно запоминать и весь заказ, чтобы он не пропадал при перезагрузке. Массив попадает в localStorage в виде текста JSON, как в курсе JavaScript, так что с этим мог бы справиться такой же наблюдатель, как для имени:
watch(order, (value) => {
localStorage.setItem("order", JSON.stringify(value));
});Но этот наблюдатель никогда не срабатывает. Наблюдатель рефа срабатывает, когда в его .value попадает что-то новое, например order.value = []. push() не кладёт в order.value новый массив, а изменяет тот, что уже там. То же делает inOrder.count++, который изменяет объект внутри массива. Страница эти изменения показывает, но наблюдатель не заглядывает внутрь массива, пока его об этом не попросят. Попросить можно третьим аргументом — настройками { deep: true }:
watch(
order,
(value) => {
localStorage.setItem("order", JSON.stringify(value));
},
{ deep: true },
);Это тот же вызов, watch(order, function, options), только каждый аргумент записан на отдельной строке: так обычно записывают вызов, если функция — не последний аргумент. Теперь Vue запускает функцию после любого изменения внутри массива, а также внутри объектов в нём.
При запуске приложение читает заказ обратно с помощью JSON.parse(), а если ничего не сохранено, начинает с пустого массива:
const saved = localStorage.getItem("order");
const order = ref(saved === null ? [] : JSON.parse(saved));Типичные ошибки:
- Забыть
{ deep: true }. Ничего не сохраняется, и никакая ошибка не объясняет почему. - Сохранять без
JSON.stringify(). Тогда вlocalStorageлежит[object Object], а при запуске приложенияJSON.parse()завершается ошибкойSyntaxError.
Задание
- 1
Каждый раз, когда заказ меняется, сохраняйте его в
localStorageпод ключомorderв виде текста JSON. Попробуйте добавить несколько позиций, в том числе одну и ту же дважды. - 2
При запуске приложения прочитайте сохранённый заказ, а если ничего не сохранено, начните с пустого. Добавьте несколько позиций и нажмите «Запустить»: заказ и его сумма остаются.