@RudMa

Интегрировать корзину на Vue.js, не пойму как подтянуть данные из localStorage?

Стоит задача интегрировать корзину отдельным компонентом на Vuejs.js в готовый проект, написанный не на Vuejs. Есть функция добавления товара в корзину, которая сохраняет данные в localStorage.

let addToCartBtns = document.querySelectorAll('.js-add2cart');
let cartBtns = document.querySelectorAll(".bcart__button");
let input = document.querySelector(".qty__input");
let plusBtn = document.querySelector(".qty__change--plus");
let minusBtn = document.querySelector(".qty__change--minus");
let notification = document.querySelector("#product-added");

let products = [
    {
      id: 1,
      name: "Поролон мебельный ST 2236 (1,6х2м) толщина 10мм",
      price: 440,
      pic: "assets/content-images/cart-1.jpg",
      qty: 0
    },
    {
      id: 2,
      name: "Утеплитель ZE Строй «Коттедж +», упаковка  ",
      price: 840,
      pic: "assets/content-images/cart-2.jpg",
      qty: 0
    },
    {
      id: 3,
      name: "Короткое название",
      price: 110000,
      qty: 0
    },
    {
      id: 4,
      name: "Какой-то товар с очень длинным названием, например... ну просто с очень-очень-очень длинным названием",
      price: 0,
      pic: "assets/content-images/cats-2.png",
      qty: 0
    },
    {
      id: 5,
      name: "Какой-то бренд Какой-то товар с длинным названием",
      price: 1500450,
      pic: "assets/content-images/about-1.png",
      qty: 0
    }
  ]
; 

function activateCart () {
  for (let i = 0; i < cartBtns.length; i++) {
    cartBtns[i].classList.add("bcart__button--active");
  }
}

if (plusBtn) {
  (function () {
      plusBtn.addEventListener("click", () => {
        input.value = parseInt(input.value) + 1;
    });
  })()
}
if (minusBtn) {
  (function() {
    minusBtn.addEventListener("click", () => {
      if (input.value > 1) {
        input.value = parseInt(input.value) -1;
      } else input.value = 1;
    });
  })()
}
for (let i = 0; i < addToCartBtns.length; i++) {
  addToCartBtns[i].addEventListener("click", () => {
    notification.classList.add("notification--opened");
    qtyChanger(products[i]);
    totalCost(items[i]);
  });
}

function qtyChanger(product) {
  let productQty= localStorage.getItem('qty');

  productQty= parseInt(productQty);

  if(productQty) {
    localStorage.setItem("qty", productQty + parseInt(input.value));
  } else {
    localStorage.setItem("qty", input.value);
    activateCart();
  } 
  setItems(product);
  
}

function setItems(product) {
  let cartItems = localStorage.getItem("productsInCart");
  cartItems = JSON.parse(cartItems);
if (cartItems !== null) {
  if (cartItems[product.id] == undefined) {  
    cartItems = {
      ...cartItems,
      [product.id]: product
    }
  }
      cartItems[product.id].qty += parseInt(input.value);
    } else {
      product.qty = parseInt(input.value);
      cartItems = {
        [product.id]: product
      };
    }

  localStorage.setItem("productsInCart", JSON.stringify(cartItems));
}

function totalCost(item) {
  let cartCost = localStorage.getItem("totalCost");
  
  if(cartCost !== null) {
    cartCost = parseInt(cartCost);
    localStorage.setItem(
      "totalCost",
      cartCost + item.priceCurrent * parseInt(input.value)
    );
  } else {
    localStorage.setItem("totalCost", item.priceCurrent);
  }
}

function onLoadProductQty() {
  let productQty = localStorage.getItem("qty");

  if(productQty) {
    activateCart()
  }
}

onLoadProductQty();


Не подтягиваются данные в самой корзине из localStorage. В консоли в сафари пишет, что не может распарсить JSON, в хроме без ошибок.
Это store.js, где я прописываю все действия с корзиной
import {
  createApp
} from 'vue';

import {
  createStore
} from 'vuex';


let store = createStore({
  state: {
    products: localStorage.getItem('productsInCart') ? JSON.parse(localStorage.getItem('productsInCart')) : []
  },
  mutations: {
    CHANGE_LOCALSTORAGE: (state, products) => {
      localStorage.setItem("productsInCart", JSON.stringify(state.products));
    },
    REMOVE_ITEM_FROM_CART: (state, index) => {
      state.products.splice(index, 1);
    },
    REMOVE_ALL_PRODUCTS_FROM_CART: (state, products) => {
      state.products.length = 0;
    },
    INCREMENT: (state, index) => {
      state.products[index].qty++;
    },
    DECREMENT: (state, index) => {
      if (state.products[index].qty > 1) {
        state.products[index].qty--;
      }
    },
    ACTIVATE_CART: () => {
      let cartBtns = document.querySelectorAll(".bcart__button");
      for (let i = 0; i < cartBtns.length; i++) {
        cartBtns[i].classList.add("bcart__button--active");
      }
    },
    DEACTIVATE_CART: () => {
      let cartBtns = document.querySelectorAll(".bcart__button");
      for (let i = 0; i < cartBtns.length; i++) {
        cartBtns[i].classList.remove("bcart__button--active");
      }
    }
  },
  actions: {
    SET_PRODUCTS_TO_LOCALSTORAGE({
      commit,
      products
    }) {
      commit("CHANGE_LOCALSTORAGE", this.products);
      commit("ACTIVATE_CART");
    },
    DELETE_PRODUCT_FROM_CART({
      commit,
      index
    }) {
      commit("REMOVE_ITEM_FROM_CART", index);
    },
    DELETE_ALL_PRODUCTS_FROM_CART({
      commit
    }) {
      commit("REMOVE_ALL_PRODUCTS_FROM_CART");
    },
    INCREMENT_CART_PRODUCT({
      commit
    }, index) {
      commit("INCREMENT", index);
    },
    DECREMENT_CART_PRODUCT({
      commit
    }, index) {
      commit("DECREMENT", index);
    },
    ACTIVATE_CART_STATUS({
      commit
    }) {
      commit("ACTIVATE_CART");
    },
    DEACTIVATE_CART_STATUS({
      commit
    }) {
      commit("DEACTIVATE_CART");
    },
    CHANGE_STATE_LOCALSTORAGE({
      commit
    }) {
      commit("CHANGE_LOCALSTORAGE");
    }
  },
  getters: {
    PRODUCTS(state) {
      return state.products;
    }
  }
});

const app = createApp({});
app.use(store);

export default store;


А здесь я пытаюсь вызвать загрузку из storage
<div
  class="cells"
  v-if="PRODUCTS.length">
  <div class="cell cell-xl-8">
    <cart/>
  </div>
  <cart-form/>
</div>
<div class="page-message" v-else>
  <div class="page-message__icon">
    <svg width="25" height="22" viewBox="0 0 25 22" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M5.83333 4.16683L8.16667 12.3335H21L23.3333 4.16683H5.83333ZM5.83333 4.16683L5.25 1.8335H0M9.33333 20.5002C8.04467 20.5002 7 19.4555 7 18.1668C7 16.8782 8.04467 15.8335 9.33333 15.8335C10.622 15.8335 11.6667 16.8782 11.6667 18.1668C11.6667 19.4555 10.622 20.5002 9.33333 20.5002ZM19.8333 20.5002C18.5447 20.5002 17.5 19.4555 17.5 18.1668C17.5 16.8782 18.5447 15.8335 19.8333 15.8335C21.122 15.8335 22.1667 16.8782 22.1667 18.1668C22.1667 19.4555 21.122 20.5002 19.8333 20.5002Z" stroke="currentColor" stroke-width="2" stroke-linejoin="round"></path>
    </svg>
  </div>
  <div class="page-message__title">Ваша корзина пуста</div>
  <div class="page-message__text">Выберите в каталоге интересующий товар и добавьте в корзину</div>
  <div class="page-message__action">
    <a class="button button-secondary" href="catalog.html">
      <div class="button__body">Перейти в каталог</div>
      <div class="button__icon">
        <svg width="7" height="10" viewBox="0 0 7 10" fill="none" xmlns="http://www.w3.org/2000/svg">
          <path d="M1 9L5 5L1 1" stroke="currentColor" stroke-width="2"></path>
        </svg>
      </div>
    </a>
  </div>
</div>

import cart from './components/cart.vue'

import cartForm from './components/cart-form.vue'
import {mapActions, mapGetters} from 'vuex'
export default {
  components: { cartForm, cart },
  name: "app",
  data() {
    return {
    }
  },
  computed: {
    ...mapGetters([
      'PRODUCTS'
    ])
  },
   methods: {
    ...mapActions([
      'SET_PRODUCTS_TO_LOCALSTORAGE'

    ])
   },
  mounted() {
    this.SET_PRODUCTS_TO_LOCALSTORAGE()
  }
}
  • Вопрос задан
  • 280 просмотров
Пригласить эксперта
Ответы на вопрос 1
nuykon
@nuykon
Full Stack Developer
CHANGE_LOCALSTORAGE: (state, products) => {
  localStorage.setItem("productsInCart", JSON.stringify(state.products)); // здесь скорее всего надо передавать просто products
},


SET_PRODUCTS_TO_LOCALSTORAGE({
  commit,
  products
}) {
  commit("CHANGE_LOCALSTORAGE", this.products); // здесь аналогично, просто products
  commit("ACTIVATE_CART");
},


v-if="PRODUCTS.length"  -> v-if="PRODUCTS && PRODUCTS.length"


для начала так
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы