๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
โญ Personal_Study/Vue

Todo: Local Storage

by ํฌ์ŠคํŠธ์‰์ดํฌ 2022. 11. 16.

Todo: Local Storage

Local Storage ๊ฐœ์š”

โœ” ๋ธŒ๋ผ์šฐ์ €์˜ Local Storage์— todo ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜์—ฌ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์กด๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๊ธฐ

Window.localStorage

โœ” ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” ์ €์žฅ๊ณต๊ฐ„ ์ค‘ ํ•˜๋‚˜์ธ Local Storage์— ๊ด€๋ จ๋œ ์†์„ฑ
โœ” ๋งŒ๋ฃŒ๋˜์ง€ ์•Š์€ ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ข…๋ฃŒํ•˜๊ณ  ๋‹ค์‹œ ์‹คํ–‰ํ•ด๋„ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์กด๋œ๋‹ค.
โœ” ๋ฐ์ดํ„ฐ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ
โœ” ๊ด€๋ จ ๋ฉ”์„œ๋“œ

  • setItem(key, value): key, value ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐ ์ €์žฅ
  • getItem(key): key์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ

Local Storage ์‹ค์Šต

  1. ์‹ค์Šต
// index.js

export default new Vuex.Store({
  ...
  actions: {
    ...
    saveTodosToLocalStorage(context) {
      const jsonTodos = JSON.stringify(context.state.todos)
      localStorage.setItem('todos', jsonTodos)
    }
  },
  modules: {},
});

โœ” ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— JSON.stringify๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๊ณผ์ • ํ•„์š”
โœ” state๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ž‘์—…์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— mutations์ด ์•„๋‹Œ actions์— ์ž‘์„ฑ

  1. ์‹ค์Šต
// index.js

export default new Vuex.Store({
  ...
  actions: {
    createTodo(context, todoTitle) {
      // Todo ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ
      const todoItem = {
        title: todoTitle,
        isCompleted: false,
      };
      // console.log(todoItem)
      context.commit('CREATE_TODO', todoItem)
      context.dispatch('saveTodosToLocalStorage')
    },

    // ์ด ๊ฒฝ์šฐ๋Š” ์ƒ๋žตํ•˜๊ณ  ๋ฐ”๋กœ mutations ํ˜ธ์ถœ ๊ฐ€๋Šฅ
    deleteTodo(context, todoItem) {
      context.commit('DELETE_TODO', todoItem)
      context.dispatch('saveTodosToLocalStorage')
    },

    updateTodoStatus(context, todoItem) {
      context.commit('UPDATE_TODO_STATUS', todoItem)
      context.dispatch('saveTodosToLocalStorage')
    },

    saveTodosToLocalStorage(context) {
      const jsonTodos = JSON.stringify(context.state.todos)
      localStorage.setItem('todos', jsonTodos)
    }
  },
  modules: {},
});

โœ” todo ์ƒ์„ฑ, ์‚ญ์ œ, ์ˆ˜์ • ์‹œ์— ๋ชจ๋‘ saveTodosToLocalStorage action ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰๋˜๋„๋ก ํ•จ

  1. ์‹ค์Šต

โœ” local storage์— ์ €์žฅ๋œ ๊ฒƒ ํ™•์ธ

  1. ์‹ค์Šต

โœ” ์•„์ง Local Storage์— ์žˆ๋Š” todo๋ชฉ๋ก์„ ๋ถˆ๋Ÿฌ์˜จ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•ด์•ผ ํ•œ๋‹ค.

  1. ๋ถˆ๋Ÿฌ์˜ค๊ธฐ ๋ฒ„ํŠผ ์ž‘์„ฑ
// App.vue

<template>
  <div id="app">
    <h1>Todo List</h1>
    <h2>All Todos: {{ allTodosCount }}</h2>
    <h2>Completed Todo: {{ completedTodosCount }}</h2>
    <h2>unCompleted Todo: {{ unCompletedTodosCount }}</h2>
    <TodoList/>
    <TodoForm/>
    <button @click="loadTodos">Todo ๋ถˆ๋Ÿฌ์˜ค๊ธฐ</button>
  </div>
</template>
  1. loadTodos ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
// App.vue

<script>
import TodoForm from './components/TodoForm.vue'
import TodoList from './components/TodoList.vue'

export default {
  name: 'App',
  components: {
    TodoList,
    TodoForm
  },
  methods: {
    loadTodos() {
      this.$store.dispatch('loadTodos')
    }
  },
...
}
  1. loadTodos actions ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
// index.js

export default new Vuex.Store({
  ...
  actions: {
    ...
    loadTodos(context) {
      context.commit('LOAD_TODOS')
    }
  },
  modules: {},
});
  1. LOAD_TODOS mutation ๋ฉ”์„œ๋“œ ์ž‘์„ฑ
// index.js

export default new Vuex.Store({
    ...
    LOAD_TODOS(state) {
      const localStorageTodos = localStorage.getItem('todos')
      const parsedTodos = JSON.parse(localStorageTodos)
      state.todos = parsedTodos
    }
  }),

โœ” ๋ฌธ์ž์—ด ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ object ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ (JSON.parse)ํ•˜์—ฌ ์ €์žฅ

  1. ๋™์ž‘ํ™•์ธ

vuex-persistedstate

๊ฐœ์š”

โœ” Vuex state๋ฅผ ์ž๋™์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์˜ Local Storage์— ์ €์žฅํ•ด์ฃผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ค‘ ํ•˜๋‚˜
โœ” ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ๋˜์–ด๋„ Vuex state๋ฅผ ์œ ์ง€ ์‹œํ‚จ๋‹ค
โœ” Local Storage์— ์ €์žฅ๋œ data๋ฅผ ์ž๋™์œผ๋กœ state๋กœ ๋ถˆ๋Ÿฌ์˜จ๋‹ค

์„ค์น˜ ๋ฐ ์ ์šฉ

$ npm i vuex-persistedstate
// index.js
...
import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex);

export default new Vuex.Store({
  plugins: [
    createPersistedState(),
  ],
  ...
})

โœ” ์ด์ „์— ์ž‘์„ฑํ•œ local storage ๊ด€๋ จ ์ฝ”๋“œ ์ฃผ์„ ์ฒ˜๋ฆฌ

Vuex when, how

mutations๋งŒ์œผ๋กœ state ๋ณ€๊ฒฝํ•˜๊ธฐ?

โœ” ๊ฐ€๋Šฅ์€ ํ•˜๋‚˜ ์ €์žฅ์†Œ์˜ ๊ฐ ์ปจ์…‰(state, getters, mutations, actions)์€ ๊ฐ์ž์˜ ์—ญํ• ์ด ์กด์žฌํ•˜๋„๋ก ์„ค๊ณ„ ๋˜์–ด ์žˆ๋‹ค.

โœ” todo app์ฒ˜๋Ÿผ actios์˜ ๋กœ์ง์ด ํŠน๋ณ„ํ•œ ์ž‘์—† ์—†์ด ๋‹จ์ˆœํžˆ mutations๋งŒ์„ ํ˜ธ์ถœํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์œผ๋‚˜, ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ๋Š” Vuex ๋„์ž…์˜ ์ ์ ˆ์„ฑ ํŒ๋‹จ ํ•„์š”

์–ธ์ œ Vuex๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ• ๊นŒ?

โœ” Vuex๋Š” ๊ณต์œ  ์ƒํƒœ ๊ด€๋ฆฌ ์ฒ˜๋ฆฌ์— ์œ ์šฉํ•˜์ง€๋งŒ, ๊ฐœ๋…์— ๋Œ€ํ•œ ์ดํ•ด์™€ ์‹œ์ž‘ ๋น„์šฉ์ด ํฌ๋‹ค!!
โœ” ๋‹จ์ˆœํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” Vuex ์—†์ด ํ•˜๋Š” ๊ฒƒ์ด ๋” ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Œ
โœ” ์ค‘๋Œ€ํ˜• ๊ทœ๋ชจ์˜ SPA ๊ตฌ์ถ• ์‹œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์„ ํƒ
โœ” ํ•„์š”ํ•œ ์ˆœ๊ฐ„ ์—ญํ• ์— ๋งž๊ฒŒ ์ ์ ˆํ•˜๊ฒŒ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”

'โญ Personal_Study > Vue' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Vue Router  (0) 2022.11.18
UX & UI  (0) 2022.11.18
Vuex ํ™œ์šฉํ•ด Todo SPA ์•ฑ ๋งŒ๋“ค๊ธฐ  (0) 2022.11.15
Lifecycle Hooks  (0) 2022.11.14
Vuex  (0) 2022.11.14

๋Œ“๊ธ€