본문 바로가기

ETC

12. Vuex Store ( 로그인 회원정보와 주문정보 Store )

store 디렉토리 구성

index.js

import Vue from 'vue';
import Vuex from "vuex";
import createPersistedState from 'vuex-persistedstate'
import toOrderStore from "@/store/modules/toOrderStore";
import member from "@/store/modules/member";

Vue.use(Vuex);

export const store = new Vuex.Store({
    modules: {
        member : member,
        toOrderStore : toOrderStore,
    },

    plugins: [createPersistedState({
        paths: ["member","toOrderStore"]
    })]

});

사용자 정보를 저장하는 member Store와 

주문정보를 저장하는 toOrderStore 를 가져온다.

 

vuex-persistedstate란?

이전에 정리한 새로고침시 vuex의 상태를 유지하기 위해서

 

10. 새로고침시 Vuex 상태 유지 (vuex-persistedstate)

로그인 부분을 구현하는 중 잠깐만 사이트를 이동하거나 새로고침을 하면 state가 모두 초기화 되어서 화면 데이터가 다 날라간다. 나는 로그인 구현이 다 끝나고 설치를 했지만.. (꼭..) 미리 설

dwc04112.tistory.com

 

해당 스토어의 데이터는 

this.$store.state.모듈이름.가져올정보

형식으로 가져와 사용이 가능하다.

 

 

1. Member 

import axios from "axios";

const userData = () => {
    return {
        mid : void 0,
        nickName: void 0,
        fullName: void 0,
        phoneNum: void 0,
        profilePicture : void 0,
        userRule : void 0,
    }
}

const loginData = () => {
    return {
        loginState: false,
        email: void 0,
        token: void 0,
    }
}

const member = {
    state: {
        loginData: loginData(),
        userData: userData(),
    },

    mutations: {
        loginData: function (state, data) {
            state.loginData.email = data.email
            state.loginData.token = data.token
            state.loginData.loginState = true
            console.log("log State : ", state.loginData)
        },


        initData (state){
            state.userData = userData();
            state.loginData = loginData();
            console.log(state)
        },

        putProfile: function (state, data){
            state.userData.nickName = data.nickName
            state.userData.profilePicture = require('@/assets/profile_imgs/'+data.profilePicture)
            console.log(state.userData)
        },

        putUserInfo: function (state, data){
            state.userData.fullName = data.fullName
            state.userData.nickName = data.nickName
            state.userData.mid = data.mid
            state.userData.phoneNum = data.phoneNum
            state.userData.profilePicture = require('@/assets/profile_imgs/'+data.profilePicture)
            state.userData.userRule = data.userRule
            console.log("putUserInfo : " + state)
        },
    },

    actions: {

        login ({commit, dispatch}, payload){
            let data = {};
            data.email = payload.email
            data.token = payload.token
            return new Promise((resolve) => {
                setTimeout(() => {
                    commit('loginData', data);
                    resolve()
                }, 500)
            }).then(()=> dispatch('getUserInfo', data.email))
        },

        logout({commit}){
            return new Promise((resolve) => {
                setTimeout(() => {
                    axios.post("/logout")
                        .then(() => {
                            commit('initData');
                        }).catch(error =>{
                            console.log(error.response);
                        })
                    resolve()
                }, 1000)
            })
        },

        getUserInfo: function ({commit}, payload) {

            return new Promise((resolve) => {
                setTimeout(() => {

                let data = {};
                data.email = payload
                axios.post('/user/info', JSON.stringify(data), {
                    headers: {
                        "Content-Type": `application/json`,
                    },
                })
                    .then((res) => {
                        console.log(res.data)
                        data.nickName = res.data.nickName
                        data.fullName = res.data.fullName
                        data.mid = res.data.mid
                        data.phoneNum = res.data.phoneNum
                        data.profilePicture = res.data.profilePicture
                        data.userRule = res.data.userRule
                    }).catch((error) => {
                        console.log(error.res)
                    }).then(()=>{
                        commit('putUserInfo', data);
                    })
                    resolve()
                }, 1000)
            })
        },

        updateProfile: function ({commit}, payload) {
            let data = {};
            data.nickName = payload.nickName;
            data.profilePicture = payload.profilePicture;

            return new Promise((resolve) => {
                setTimeout(() => {
                    commit('putProfile', data);
                    resolve()
                }, 1000)
            })
        },

        loginCheck_401: function ({commit}){
                return new Promise((resolve) => {
                    setTimeout(() => {
                        commit('initData');
                        resolve()
                    }, 1000)
                }
            )
        },



    },
}


export default member;

 

동작 순서를 보자면

vue 컴포넌트에서 dispatch -> Action -> mutation -> state 변경

Mutations 에는 순차적인 로직들을 Actions 에는 비 순차적 또는 비동기 처리를

따라서 Action에는 get 요청을 처리해주고 아래와 같이 딜레이를 줘서 순서를 지정해준다.

 

   return new Promise((resolve) => {
            setTimeout(() => {
                commit('initData');
                resolve()
            }, 1000)
        }

 

왜 State를 loginData와 UserData로 나눴나?

state를 초기화 시켜줘야 할 때 일일히 초기화 시키지 않고 한번에 초기화가 가능하고 (제일 큰 이유),

각각의 사용처가 달라서 

 

 

1-1 action : login -> initData -> login-> getUserInfo 

로그인시 dispatch로 login으로. 우선 남아있는 정보들이 있을 수 있으므로 데이터를 초기화시킨다 (commit initData)

넘겨받은 이메일과 토큰을 commit > mutation으로넘겨 State에 저장 후 

getUserInfo로 다시 dispatch하여 나머지 정보도 넘겨받고 저장

 

 

1-2 action : UpdateProfile

마이페이지의 수정이나 회원가입 후 프로필을 지정할때 dispatch하는 액션이다.

 

1-3 action : loginCheck_401 

401 인증에러가 발생하면 initData를 commit하여 정보를 초기화 시켜준다.

 

 

 

2. toOrderStore

 

const toOrderStore = {

    state: {
        bookList : [],
    },

    mutations: {
        clearState: function (state){
            state.bookList = null;
        },
        setOrder: function (state, data) {
            state.bookList = data
        },

    },

    actions: {

        // cart에서 주문목록 받아오기
        getOrderByCart({commit}, payload){
            return new Promise((resolve) => {
                setTimeout(() => {
                    commit('clearState');
                    resolve()
                }, 500)
            }).then(()=>  commit('setOrder', payload))
        },

        // detail에서 주문목록 받아오기
        getOrderByDetail({commit}, payload){
            return new Promise((resolve) => {
                setTimeout(() => {
                    commit('clearState');
                    resolve()
                }, 500)
            }).then(()=>  commit('setOrder', payload))
        },

        clearOrderState({commit}){
            return new Promise((resolve) => {
                setTimeout(() => {
                    commit('clearState');
                    resolve()
                }, 500)
            })
        }
    },
}
export default toOrderStore;

장바구니에서 구매하거나 바로 구매할때 책들의 정보가 저장되는 Store이다.

 

2-1. getOrderByCart (장바구니에서 주문)

getOrderByCart 에서 여러개의 책과 다양한 수량을 쉽게 저장 할 수 있다.

 

2-2. getOrderByDetail (책 상세보기에서 주문)

 한 종류의 책을 주문할 때 상세보기 페이지에서 dispatch된다.

 

2-3. clearOrderState (초기화)

책 정보를 결제컴포넌트에 넘겨주고 항상 초기화 시켜줘야한다.

안그러면 다른 주문에서 전에 사용한 데이터가 넘어온다