Как можно сохранить данные товаров при перезагрузке страницы во Vue.js приложении, чтобы они не исчезали?

Как можно избежать проблемы с исчезновением товара и предупреждениями после перезагрузки страницы на роуте товара?
  • 20 октября 2023 г. 12:38
Ответы на вопрос 2
1. Для сохранения данных при перезагрузке страницы во Vue.js приложении, можно использовать localStorage или sessionStorage. Оба этих API позволяют сохранять данные на стороне клиента.

2. При добавлении или изменении товара в корзине, сохраните его данные в localStorage или sessionStorage вместе с другими данными, которые вы хотите сохранить. Например:

```javascript
// При добавлении товара в корзину
addToCart(product) {
  // Получаем сохраненные данные товаров из localStorage или sessionStorage
  const savedCart = JSON.parse(localStorage.getItem('cart')) || [];

  // Добавляем новый товар в сохраненные данные
  savedCart.push(product);

  // Сохраняем данные обратно в localStorage или sessionStorage
  localStorage.setItem('cart', JSON.stringify(savedCart));
}
```

3. При загрузке страницы в компоненте, вы можете проверить наличие сохраненных данных и использовать их при необходимости:

```javascript
// В методе created или mounted компонента
mounted() {
  // Получаем сохраненные данные товаров из localStorage или sessionStorage
  const savedCart = JSON.parse(localStorage.getItem('cart')) || [];

  // Используем сохраненные данные, например, для отображения товаров в корзине
  this.cart = savedCart;
}
```

4. Чтобы избежать проблемы с исчезновением товара и предупреждениями после перезагрузки страницы на роуте товара, можно использовать технику «обещания» (promises) и метод `beforeRouteEnter`. При переходе на роут товара, вы можете сначала проверить наличие сохраненных данных и затем отображать товар или перенаправлять на другую страницу, если он не найден:

```javascript
beforeRouteEnter(to, from, next) {
  // Получаем сохраненные данные товаров из localStorage или sessionStorage
  const savedProducts = JSON.parse(localStorage.getItem('products')) || [];

  // Ищем товар с нужным идентификатором в сохраненных данных
  const product = savedProducts.find(p => p.id === to.params.id);

  if (product) {
    // Если товар найден, передаем его в функцию next и отображаем роут товара
    next(vm => vm.showProduct(product));
  } else {
    // Если товар не найден, перенаправляем на другую страницу
    next('/not-found');
  }
}
```

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

Определите переменные products в качестве ref. В текущей реализации они не являются реактивными (не реагируют на изменения). При этом вы присваиваете массиву значение value. Как это работало ранее - непонятно.

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

В целом, если загрузка должна начинаться в любом случае при первой инициализации стора (обычно загрузку привязывают к маршрутам или компонентам), то выглядеть это будет примерно так:

```javascript
export const useAllMainFiltersStore = defineStore('allMainFilters', () => {
  const products = ref([]);

  try {
    async function getStoreData() {
      sidebarResizeStore.updateSidebarVisibility();
      const data = await productsData();
      products.value = data;
    }
    getStoreData();
  } catch (error) {
    console.error('Error:', error);
  }
  
  return {
    products,
  };
})

В компоненте:

const route = useRoute();
// продукт делаем вычисляемым, чтобы избежать наблюдения
const product = computed(() => getProductById(route.params.id));

function getProductById(id) {
  console.log('products component: ', mainFiltersStore.products) //при первой загрузке всё ок, при перезагрузке страницы всё ломается и пустой массив в придачу
  return products.find(product => product.id == id);
}

watch(product, current => {
  // проверяем, что продукт есть
  if (current) fetchComments(current.id);
}, { immediate: true })
```
Похожие вопросы