Natalia
Natalia

Reputation: 1027

Add localStorage to Vue JS 2 app

I wanna add the localStorage to my shopping cart app in Vue JS 2 to save items in a cart when user reload the page and to save quantity of items, when user clicks on + or - buttons. How can I do that? I'm new in VueJS. Ihave tried to solve it by adding itemStorage.fetch() into shopping cart component, but it does not work.

This is what I have so far. Unfortunately I didn't split it into smaller components :(

const apiURL = 'https://api.myjson.com/bins/1etx1x';

const STORAGE_KEY = 'vue-js-todo-P7oZi9sL'
let itemStorage = {
  fetch: function() {
    let items = JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]')
    return items;
  },
  save: function(items) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(items));
    console.log('items saved')
  }
}

Vue.filter('addCurrency', val => val.toFixed(2) + ' $');

Vue.component('shopping-cart', {
  props: ['items'],
  data: function() {
    return {
      //item: this.items
      item: itemStorage.fetch()
    };
  },
  watch: {
    items: {
      handler: function(items) {
        itemStorage.save(items);
      }
    }
  },
  computed: {
    total: function() {
      let total = 0;
      this.items.map(item => {
        total += (item.price * item.quantity);
      });
      return total;
    }
  },
  methods: {
    removeItem(index) {
      this.items.splice(index, 1)
    },
    addOne: item => {
      item.quantity++;
    },
    subtractOne: item => {
      item.quantity--;
    },
    removeAll() {
      return this.item.splice(0, this.item.length);
    }
  }
});

const vm = new Vue({
  el: '#shop',
  data: {
    cartItems: [],
    //items: [],
    items: itemStorage.fetch(),
    addToCartBtn: 'Add to cart',
    showCart: false,
    isInCart: 'In cart',
    search: '',
    sortType: 'sort',
    sortOptions: [{
        text: 'choose',
        value: 'sort'
      },
      {
        text: 'name',
        value: 'name'
      },
      {
        text: 'price',
        value: 'price'
      }
    ]
  },
  created: function() {
    this.fetchData();
  },

  computed: {
    products: function() {
      return this.items.filter(item => item.name.toLowerCase().indexOf(this.search.toLowerCase()) >= 0);
    }
  },
  methods: {
    fetchData() {
      axios.get(apiURL)
        .then(resp => {
          this.items = resp.data
        })
        .catch(e => {
          this.errors.push(e)
        })
    },
    sortBy(sortKey) {
      this.items.sort((a, b) =>
        (typeof a[sortKey] === 'string' || typeof b[sortKey] === 'string') ? a[sortKey].localeCompare(b[sortKey]) : a[sortKey] - b[sortKey]);
    },
    toggleCart: function() {
      this.showCart = !this.showCart;
    },
    addToCart(itemToAdd) {
      let found = false;
      this.showCart = true;
      this.cartItems.map(item => {
        if (item.id === itemToAdd.id) {
          found = true;
          item.quantity += itemToAdd.quantity;
        }
      });
      if (found === false) {
        this.cartItems.push(Vue.util.extend({}, itemToAdd));
      }
      itemToAdd.quantity = 1;
    },
    itemInCart(itemInCart) {
      let inCart = false;
      this.cartItems.map(item => {
        if (item.id === itemInCart.id) {
          inCart = true;
        }
      });
      if (inCart === false) {
        return this.isInCart;

      }
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js"></script>

Upvotes: 1

Views: 2084

Answers (2)

arve0
arve0

Reputation: 3647

To persist state, you may use the plugin vue-persistent-state like this:

import persistentStorage from 'vue-persistent-storage';

const initialState = {
  items: []
};
Vue.use(persistentStorage, initialState);

Now items is available as data in all components and Vue instances. Any changes to this.items will be stored in localStorage, and you can use this.items as you would in a vanilla Vue app.

If you want to understand how this works, the code is pretty simple. It basically

  1. adds a mixin to make initialState available in all Vue instances, and
  2. watches for changes and stores them.

Disclaimer: I'm the author of vue-persistent-state.

Upvotes: 1

For the Name
For the Name

Reputation: 2529

You can use localStorage.getItem() and localStorage.setItem(), but in my experience using localStorage does not work well with Vue. I would have all kinds of weird, unexplained problems. I think it's just not fast enough. You should instead look into using Vuex and setting up Vuex persisted state to automatically sync it to session/local storage.

Upvotes: 1

Related Questions