3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Nuxtでショッピングカートに商品情報を追加する

Posted at

目的

個人開発してるサービスでカート機能を実装したい
今回はカートに入れるボタンを押下したらカートに商品情報が入るようにしたい

参考サイト

Nuxt.jsのStoreによるデータ保存 [vuex-persistedstate][js-cookie]

Vuex でショッピングカートを実装できる無料コース「Vuex for Everyone」を受講した

仕様

カートに入れる情報は下記を想定

  • イベントID
  • 商品ID
  • 個数
  • 区分(すぐ買う/後から配送)

同じ商品情報が存在した場合は、個数をインクリメントする
1週間ほどはカート情報は保持しておきたい

実装

カート情報を入れるVuexの実装

仕様でも書いたとおりカートには下記の情報を保持するようにする

  • イベントID
  • 商品ID
  • 個数
  • 区分(すぐ買う/後から配送)

イベントIDと商品IDと区分の同一なデータが有ればINCREMENT_QUANTITYが無ければPUSH_PRODUCT_TO_CARTが実行されるようにする

store/cart.js
export const getters = {
  getCartProducts(state) {
    return state.products
  }
}

export const state = () => ({
  products: []
})

export const mutations = {
  PUSH_PRODUCT_TO_CART(state, payload) {
    state.products.push({
      eventId: payload.rootState.event_info.eventSelected.id,
      id: payload.product.id,
      quantity: 1,
      // カート追加時にイベントが開催中であれば、配送の区分を0(今すぐ受取る)にする
      // 終了後であれば配送区分を1(自宅へ配送)に設定する
      delivery:
        new Date(
          payload.rootState.event_info.eventSelected.end_date
        ).getTime() > new Date().getTime()
          ? 0
          : 1
    })
  },
  INCREMENT_QUANTITY(state, payload) {
    payload.cartItem.quantity++
  }
}

export const actions = {
  addProductToCart({ commit, rootState, state }, product) {
    const cartItem = state.products.find(
      item =>
        item.id === product.id &&
        item.eventId === rootState.event_info.eventSelected.id &&
        (item.delivery ===
        new Date(rootState.event_info.eventSelected.end_date).getTime() >
          new Date().getTime()
          ? 0
          : 1)
    )

    if (!cartItem) {
      commit('PUSH_PRODUCT_TO_CART', { rootState, product })
    } else {
      commit('INCREMENT_QUANTITY', { rootState, cartItem })
    }
  }
}

カート追加処理を実装

呼び出し部分

<div class="field-button">
      <input
        type="submit"
        class="button is-blue is-large is-fullwidth"
        value="カートに入れる"
        @click="addProductToCart(product)"
      />
</div>

カート追加するVuexのAction呼び出し

addProductToCart(product) {
    this.$store.dispatch('cart/addProductToCart', product)
}

カート商品情報の永続化設定

Vuexは、ブラウザを更新したらデータが消えてしまうため
永続化を行うために下記を行う

モジュールをインストール

vuex-persistedstate
vuexを永続化させるためのモジュール
https://github.com/robinvdvleuten/vuex-persistedstate

js-cookie
cookieをnuxtで使用するためのモジュール
https://github.com/js-cookie/js-cookie

npm install vuex-persistedstate
npm install js-cookie

永続化の設定

plugins/cookie-storage.js
import createPersistedState from 'vuex-persistedstate'
import * as Cookies from 'js-cookie'

const cookieStorage = {
  getItem: function(key) {
    return Cookies.getJSON(key)
  },
  setItem: function(key, value) {
    return Cookies.set(key, value, { expires: 7, secure: true })
  },
  removeItem: function(key) {
    return Cookies.remove(key)
  }
}

export default context => {
  createPersistedState({
    key: 'products-cart',
    paths: ['cart.products'],
    storage: cookieStorage,
    getState: cookieStorage.getItem,
    setState: cookieStorage.setItem
  })(context.store)
}

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?