๐Ÿ”ฅVueJS, VueX ๋ฐ VueX Persisted State๋ฅผ ์‚ฌ์šฉํ•œ ์˜๊ตฌ ์ €์žฅ์†Œ ๐Ÿ”ฅ

13824 ๋‹จ์–ด vuevuexweb
๋•Œ๋กœ๋Š” ๋ธŒ๋ผ์šฐ์ € ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ผ๋ถ€ ์ •๋ณด๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด VueJS ์›น ์•ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ์„ค์ •, ๊ณ„์ • ์ •๋ณด ๋˜๋Š” ์ผ๋ถ€ ํ† ํฐ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ๋˜๋ฉด ์ ˆ๋Œ€ ์žƒ์–ด๋ฒ„๋ฆฌ๊ณ  ์‹ถ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ๋น ๋ฅธ ์˜ˆ์ œ์—์„œ๋Š” vuex ๋ฐ vuex-persistedstate๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋งˆ๋ฒ•์„ ์ผ์œผํ‚ค๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค!

VueJS ํ”„๋กœ์ ํŠธ๋ฅผ ์ด๋ฏธ ์ƒ์„ฑํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด vuex ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ธ ์ถ”๊ฐ€ ์ข…์†์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
npm install --save vuex
์‹œ์ž‘ ์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ main.js
โ”œโ”€โ”€ components
โ”‚   โ”œโ”€โ”€ App.vue

์ƒ์  ์ƒ์„ฑ์„ ์‹œ์ž‘ํ•˜๋ ค๋ฉด store ๋ฐ components์™€ ๋™์ผํ•œ ์ˆ˜์ค€์— main.js ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ƒˆ๋กœ ์ƒ์„ฑ๋œstore ๋””๋ ‰ํ† ๋ฆฌ ๋‚ด๋ถ€์— index.js๋ฅผ ์ƒ์„ฑํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ๋งค์žฅ ๊ตฌ์„ฑ์„ ์œ„ํ•œ ์ฐธ์กฐ ์ง„์ž…์ ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‚ด๋ถ€store/index.js ํŒŒ์ผ์—์„œ ์Šคํ† ์–ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋‚ด๋ณด๋‚ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

const store = new Vuex.Store({
});

export default store

๊ทธ๊ฒŒ ๋‹ค์•ผ! ์šฐ๋ฆฌ ๊ฐ€๊ฒŒ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค!

์ด์ œ ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ main.js
โ”œโ”€โ”€ components
โ”‚   โ”œโ”€โ”€ App.vue
โ””โ”€โ”€ store
    โ”œโ”€โ”€ index.js

๋‹ค์Œ ๋‹จ๊ณ„๋Š” ๋งค์žฅ์„ ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด main.js ํŒŒ์ผ ๋‚ด๋ถ€์—์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

import Vue from 'vue'
import App from './components/App'
import store from './store';

Vue.config.productionTip = false

new Vue({
  el: '#app',
  store,
  template: '<App/>',
  components: { App }
})

๋†€๋ผ์šด! ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ ๋…ผ๋ฆฌ๋Š” ์–ด๋–ป์Šต๋‹ˆ๊นŒ?

์ด์ œ ์ผ๋ถ€ ์‚ฌ์šฉ์ž ID ์ •๋ณด๋ฅผ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์˜ ๊ฒฝ์šฐ ๋กœ๊ทธ์ธ(์‚ฌ์šฉ์ž ID๋ฅผ ์„ค์ •ํ•จ) ๋ฐ ๋กœ๊ทธ์•„์›ƒ(์‚ฌ์šฉ์ž ID๋ฅผ null๋กœ ์„ค์ •ํ•จ)์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € modules ํด๋”์— store ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋…ผ๋ฆฌmodules๋Š” ์ผ๋ถ€ ์ปจํ…์ŠคํŠธ์— ๋”ฐ๋ผ ์ €์žฅ์†Œ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‹จ์ผ ํŒŒ์ผ๊ณผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†๋Š” ์ดˆ๋Œ€ํ˜• ์ €์žฅ์†Œ๋กœ ๋๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
modules ๋‚ด๋ถ€์—์„œ ์ด์ œ ํ•„์š”ํ•œ ๋ชจ๋“  ๋…ผ๋ฆฌ๋กœ account.js๋ฅผ ๋งŒ๋“ค ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค.

const state = {
  userId: null
};

const mutations = {
  logout(state) {
    state.userId = null;
  },
  login(state, userId) {
    state.userId = userId;
  }
};

export default {
  state,
  mutations
}

๊ทธ๋ž˜์„œ, ์—ฌ๊ธฐ์„œ ๋ฌด์Šจ ์ผ์ด ์ผ์–ด๋‚˜๊ณ  ์žˆ์Šต๋‹ˆ๊นŒ?

๋จผ์ € userId ๋ผ๋Š” ๋‹จ์ผ ๋ณ€์ˆ˜๋กœ store ์†์„ฑ์„ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ null ์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ mutations ๋ฐ login ์˜ ๋‘ ๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š” logout ๋ผ๋Š” ํ•ญ๋ชฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ์•„์ด๋””์–ดvuex๋Š” ์ƒ์ ์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜๋Š” ์ปค๋ฐ‹ ์‹œ์—๋งŒ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

์šฐ๋ฆฌ ํ”„๋กœ์ ํŠธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ main.js
โ”œโ”€โ”€ components
โ”‚   โ”œโ”€โ”€ App.vue
โ””โ”€โ”€ store
    โ”œโ”€โ”€ index.js
    โ”œโ”€โ”€ modules
         โ”œโ”€โ”€ account.js

ํ•˜์ง€๋งŒ ์ƒˆ๋กœ ์ƒ์„ฑ๋œ account.js์— ๋Œ€ํ•ด ๋งค์žฅ์—์„œ ์–ด๋–ป๊ฒŒ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!

์šฐ๋ฆฌstore/index.js ๋‚ด๋ถ€์—์„œ ํ•ด๋ด…์‹œ๋‹ค:

import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    account,
  }
});

export default store

๋ณด์‹œ๋‹ค์‹œํ”ผ, ์šฐ๋ฆฌ๋Š” ๋‹จ์ˆœํžˆ account.js๋ฅผ ๊ฐ€์ ธ์™€ ์Šคํ† ์–ด์˜ ๋ชจ๋“ˆ ๋‚ด์—์„œ ์ฐธ์กฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์‰ฌ์šด!

์šฐ๋ฆฌ์˜ ๋†€๋ผ์šด ๊ฐ€๊ฒŒ๋ฅผ ์‹œํ—˜ํ•ด ๋ณผ ์‹œ๊ฐ„์ž…๋‹ˆ๋‹ค!

๋‚ด๋ถ€App.vue:

<template>
  <div>
    <div>{{this.userId}}</div>
    <button @click="login()">Login as Nick</button>
    <button @click="logout()">Logout</button>
  </div>
</template>

<script>
    import { mapState } from 'vuex'

    export default {
        name: 'app',
        computed: mapState({
            userId: state => state.account.userId
        }),
        methods: {
            login() {
                this.$store.commit('login', 'Nick')
            },
            logout() {
                this.$store.commit('logout')
            }
        },
    }
</script>

์ด ์˜ˆ์ œ์—์„œ๋Š” ๊ธ€๋กœ๋ฒŒ ์ƒํƒœ๋ฅผ ๋กœ์ปฌ ์ €์žฅ์†Œ ์†์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” mapState vue ์†์„ฑ ๋‚ด๋ถ€์˜ vuex์—์„œ computed๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ „์—ญ ์ €์žฅ์†Œ์—์„œ ๋ณ€๊ฒฝ๋œ ์‚ฌํ•ญ์ด ์žˆ์œผ๋ฉด ๊ตฌ์„ฑ ์š”์†Œ ์†์„ฑ์—์„œ๋„ ๋ณ€๊ฒฝ๋ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ this.userId ์ปจํ…์ŠคํŠธ์˜ ๊ธ€๋กœ๋ฒŒ ์ €์žฅ์†Œ์—์„œ ์ง์ ‘ ๋งคํ•‘๋˜๋Š” account ๋ฅผ ๊ฐ„๋‹จํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ์œผ๋กœ login ๋ฐ logout ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ๋ณผ ์ˆ˜ ์žˆ๋“ฏ์ด ์Šคํ† ์–ด๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ด์ „์— account mutations ์†์„ฑ์— ์ง€์ •๋œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ฐ•! ์šฐ๋ฆฌ๊ฐ€ ํ•ด๋ƒˆ์–ด!

ํ•˜์ง€๋งŒ... ํŽ˜์ด์ง€๋ฅผ ์ƒˆ๋กœ๊ณ ์นจํ•˜๋ฉด...

์˜ˆ, ๋ถˆํ–‰ํžˆ๋„ ์ง€์†๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Chrome์—์„œ Application/Local Storage๋ฅผ ์—ด๋ฉด ์šฐ๋ฆฌ์˜ userId ํ”์ ์ด ์—†์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋‚˜ vuex-persistedstate๋ผ๋Š” ์†”๋ฃจ์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค!

์ƒํƒœ๋ฅผ ๋กœ์ปฌ ์ €์žฅ์†Œ์— ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
npm install --save vuex-persistedstate
๋ฐ”๋‹๋ผ ๊ตฌ์„ฑ์˜ ๊ฒฝ์šฐ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ”Œ๋Ÿฌ๊ทธ์ธ ๋‚ด๋ถ€store/index.js๋กœ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.

import Vue from 'vue'
import Vuex from 'vuex'
import account from './modules/account'
import createPersistedState from "vuex-persistedstate";

Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    account,
  },
  plugins: [createPersistedState()]
});

export default store

์ด์ œ ๋กœ๊ทธ์ธํ•œ ํ›„ ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋กœ๋“œํ•˜๋ฉด ๋ธŒ๋ผ์šฐ์ €์˜ ๋กœ์ปฌ ์ €์žฅ์†Œ์— ์œ ์ง€๋ฉ๋‹ˆ๋‹ค!

์ž˜ํ–ˆ์–ด, ํ•ด๋ƒˆ์–ด! ์ด์ œ ๋‹น์‹ ์˜ ์•ฑ์€ ์ง„์ •์œผ๋กœ ๋ฌผ๊ฑด์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

๋” ๋งŽ์€ ์ฐธ์กฐ๋ฅผ ๋ณด๋ ค๋ฉด ์—ฌ๊ธฐ๋กœ ์ด๋™ => https://vuex.vuejs.org/

์ข‹์€ ์›นํŽ˜์ด์ง€ ์ฆ๊ฒจ์ฐพ๊ธฐ