S
S
Sergey2019-07-12 09:39:27
Vue.js
Sergey, 2019-07-12 09:39:27

How to store element class in LocalStorage?

There is a catalog, I want to organize a kind of wishlist, if a person is on the page of a catalog element, then when the button is clicked, this element was saved in favorites, when it was clicked again, it was deleted.
I added the 'persistedstate' plugin to Vuex, I seem to get the desired behavior, it remains to somehow save the class of this button, which would refer to a specific catalog element.
There is an idea to add the isLiked property when saving an element to the wishlist array, and check for this property in mounted, but I don’t know how to do everything correctly.
Button

<button ref="buttonLike" @click="putLike()" :class="buttonLike" class="like"></button>

  computed: {
    buttonLike: function () {
      return {
        liked: this.isLiked
      }
    }
  }

Method
putLike: function () {
      if (this.$refs.buttonLike.classList.contains('liked')) 
      {
        this.isLiked = !this.isLiked
        this.$store.commit('removeGame', this.game)
        console.log(this.$store.state.wishlist)
      } else {
        this.isLiked = !this.isLiked
        this.$store.commit('addGame', this.game)
        console.log(this.$store.state.wishlist)
      }
    }

store.js
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
import VueAxios from 'vue-axios'
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

export default new Vuex.Store({
  namespaced: true,
  state: {
    games: [],
    wishlist: []
  },
  plugins: [
    createPersistedState ()
  ],
  getters: {
    showAllGames: state => query => {
      return state.games.filter(game => {
        return game.title
          .toString()
          .toLowerCase()
          .includes(query.toString().toLowerCase())
      })
    },
    showHTCGames: state => query => {
      return state.games.filter(game => {
        return (game.category === 'htc' && game.title
          .toString()
          .toLowerCase()
          .includes(query.toString().toLowerCase()))
      })
    },
    showPSVRGames: state => query => {
      return state.games.filter(game => {
        return (game.category === 'psvr' && game.title
          .toString()
          .toLowerCase()
          .includes(query.toString().toLowerCase()))
      })
    },
    showPS4Games: state => query => {
      return state.games.filter(game => {
        return (game.category === 'ps' && game.title
          .toString()
          .toLowerCase()
          .includes(query.toString().toLowerCase()))
      })
    },
    showLikedGames: state => query => {
      return state.wishlist.filter(game => {
        return game.title
          .toString()
          .toLowerCase()
          .includes(query.toString().toLowerCase())
      })
    }
  },
  actions: {
    loadGames ({ commit }) {
      axios
        .get('games.json')
        .then(r => r.data.games)
        .then(games => {
          commit('SET_GAMES', games)
        })
    }
  },
  mutations: {
    SET_GAMES (state, games) {
      state.games = games
    },
    addGame (state, game) {
      state.wishlist.push(game)
    },
    removeGame (state, game) {
      state.wishlist.splice(game, 1)
    }
  }
})

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2019-07-12
Primirenkov @sergeyprimirenkov

Games elements must have a unique property that allows them to be identified, id. If it doesn't exist, add it now. These id should be stored in localStorage. So let's add the appropriate array to the state:

state: {
  wishlistIds: [],
  ...

And specify it in the persistedstate settings (yes, you can save not the entire state, but only some elements):
plugins: [
  createPersistedState({
    paths: [ 'wishlistIds' ],
  }),
  ...

Wishlist array - transfer from state to getters:
getters: {
  wishlist: state => state.games.filter(n => state.wishlistIds.includes(n.id)),
  ...

Adding/removing, respectively:
mutations: {
  addGame(state, gameId) {
    if (!state.wishlistIds.includes(gameId)) {
      state.wishlistIds.push(gameId);
    }
  },
  removeGame(state, gameId) {
    const index = state.wishlistIds.indexOf(gameId);
    if (index !== -1) {
      state.wishlistIds.splice(index, 1);
    }
  },
  ...

In the component that displays the games elements, add the calculated property liked, which will indicate whether the current element is in the wishlist and control the addition / removal:
computed: {
  liked: {
    get() {
      return this.$store.state.wishlistIds.includes(this.game.id);
    },
    set(val) {
      this.$store.commit(val ? 'addGame' : 'removeGame', this.game.id);
    },
  },
  ...

Well, the isLiked property and the putLike method are garbage, they should be cut out.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question