Избранное, которое остаётся
В уроке «Вычисляемые значения и наблюдатели» вы сохраняли заказ в localStorage через watch и читали его обратно при запуске приложения. В приложении из этого упражнения посетитель может отмечать звёздочкой любимые позиции меню, и его watch уже сохраняет их. Не хватает чтения — таким же способом, прямо при создании рефа:
const saved = localStorage.getItem("favorites");
const favorites = ref(saved === null ? [] : JSON.parse(saved));Как и раньше, null от getItem() означает, что ничего ещё не сохранено, и посетитель начинает с пустого массива.
Но это приложение ещё и загружает меню — в onMounted. Почему бы не читать избранное тоже там? Потому что localStorage отвечает сразу, а fetch() приходится ждать ответа сервера. Ждать нет смысла, поэтому читайте избранное в начале <script setup>: когда Vue впервые показывает страницу, звёздочки уже стоят правильно.
Когда это приложение запускается, данные приходят из трёх мест в три момента:
- то, что сохранено в браузере, — сразу, когда создаётся компонент,
- файл
menu.json— через мгновение после монтирования компонента, - посетитель — всякий раз, когда он щёлкает.
Вычисляемое значение, собранное из данных двух источников, верно в каждый момент. Названия любимых позиций, собранные из menu и favorites, сначала пусты, хотя идентификаторы уже есть, и появляются, когда приходит меню, — без всякого дополнительного кода.
Типичные ошибки:
JSON.parse()без проверки наnull:JSON.parse(null)даётnull, и когда шаблон читаетfavorites.includes(…), страница завершается ошибкойTypeError: Cannot read properties of null (reading 'includes'). У вас это работает, потому что вы уже что-то сохранили, а у каждого нового посетителя ломается.- Сохранение раньше чтения: если реф начинается с
[], аwatchс{ immediate: true }сразу сохраняет его, сохранённое избранное заменяется пустым массивом, прежде чем его кто-то прочитал.
Задание
- 1
При запуске приложения прочитайте сохранённое избранное и начните
favoritesс него. Проверьте: отметьте звёздочкой две позиции и нажмите «Запустить». Звёздочки останутся. - 2
Под заголовком покажите названия любимых позиций:
Ваше избранное: Капучино, Морковный торт. Сделайте их вычисляемым значением изmenuиfavoritesчерезfilter(),map()иjoin(", ")и показывайте абзац, только когда есть хотя бы одно название.