
์๋
ํ์ธ์! KB ITโs your life 7๊ธฐ ๊ธฐ์๋จ์
๋๋ค
์ ๋ ์์ฆ ์ค์ผ๋ ํค ํ๋ก์ ํธ ํ์ฐฝ ์งํ ์ค์ธ๋ฐ์!
Pinia๋ฅผ ์จ์ผ ํ๋ ์ํฉ์ด ์๋๋ฐ ๋ง์ ์ฐ๋ ค๋๊น ์์
๋ ๋ฐฐ์ ๋ ๋ด์ฉ์ด ์ ๋ฆฌ๊ฐ ์ ๋ ๋๋์ด๋๋ผ๊ณ ์...
๊ทธ๋์ ์ด๋ฒ ๊ธฐํ์ ์ ๋๋ก ๋ณต์ต ๊ฒธ ์ ๋ฆฌํด ๋ดค์ด์!
์ ์ฒ๋ผ Pinia ๊ฐ๋
์ด ์์ง ์ด๋ ต๋ค! ํ๋ ๋ถ๋ค๊ป๋
๋์์ด ๋์ผ๋ฉด ์ข๊ฒ ์ต๋๋ค ใ
ใ
Pinia ์ ์ ์์์ผ ํ ๊ฒ
Pinia๋ฅผ ์ ์จ์ผ ํ๋์ง ์ดํดํ๋ ค๋ฉด
๋จผ์ ๊ธฐ์กด ๋ฐฉ์์ธ Provide/Inject๊ฐ ๋ญ๊ฐ ๋ฌธ์ ์ธ์ง๋ถํฐ
์์์ผ ํด์!
Provide/Inject๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณต(Provide)ํ๊ณ
์์ ์ปดํฌ๋ํธ๊ฐ ๋ฐ์์(Inject) ์ฐ๋ ๋ฐฉ์์ด์์
๊ทผ๋ฐ ํ๋ก์ ํธ๊ฐ ์ปค์ง๋๊น ์ด๋ฐ ์ํฉ์ด ์๊ฒจ์
๋ฌธ์ 1. ํ์ ์ปดํฌ๋ํธ๋ผ๋ฆฌ ๋ฐ์ดํฐ ๊ณต์ ๊ฐ ์ ๋ผ์
App (Provide)
โโโ C1 (Inject ๊ฐ๋ฅ )
โโโ C2 (Inject ๊ฐ๋ฅ )
โโโ C2-1 (C1 ๋ฐ์ดํฐ ๋ชป ๋ฐ์ )Provide/Inject๋ ๊ฐ์ ํธ๋ฆฌ ์์์๋ง ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ ์ ์์ด์
C1์ด๋ C2-1์ฒ๋ผ ์๋ก ๋ค๋ฅธ ๊ฐ์ง์ ์์ผ๋ฉด ๊ณต์ ๊ฐ ์ ๋๊ฑฐ๋ ์

์ ์ฒด ์ฑ์์ ๋ค ๊ณต์ ํ๋ ค๋ฉด ๋ฌด์กฐ๊ฑด ์ต์๋จ App์์ Provide ํด์ผ ํ๋๋ฐ ๊ทธ๋ฌ๋ฉด ์ง๊ธ ๋น์ฅ ์ ์ฐ๋ ๋ฐ์ดํฐ๊น์ง ํญ์ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ ์์ด์ผ ํด์ ๋นํจ์จ์ ์ด์์.
2. ๋ฌธ์ ์ํ ๋ฐ์ดํฐ ๋ณดํธ๊ฐ ๊ฐ๋ฐ์ ์ฑ ์์ด์์
์ ์ญ์ผ๋ก ๊ณต์ ๋๋ ๋ฐ์ดํฐ๋ ์๋ฌด๋ ์์ ๋ชป ํ๊ฒ
์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋
ธ์ถํด์ผ ํด์.
๊ทผ๋ฐ Provide/Inject๋ ์ด๊ฑธ ์์คํ
์ด ๋ง์์ฃผ๋ ๊ฒ ์๋๋ผ ๊ฐ๋ฐ์๊ฐ ์ง์ ์ ๊ฒฝ ์จ์ผ ํฉ๋๋ค.
๊ทธ๋์ computed๋ก ๊ฐ์ธ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ๋
ธ์ถํ๋๋ฐ์
const readOnlyList = computed(() => state.todoList)
provide('todoList', readOnlyList) // ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ๋ฌ
provide('addTodo', addTodo) // action ํจ์๋ ๊ทธ๋๋ก OK์ด๊ฒ ์์คํ
์ด ๊ฐ์ ํด ์ฃผ๋ ๊ฒ ์๋๋ผ์
์ค์ํ๊ธฐ ๋ฑ ์ข์์ ใ
ใ
๊ทธ๋์ Pinia๊ฐ ๋ญ๋ฐ์?
Pinia(ํผ๋์)๋ Vue3์ ๊ณต์ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์
ํ๋ง๋๋ก ์ฌ๋ฌ ์ปดํฌ๋ํธ์์ ๊ณตํต์ผ๋ก ์ฐ๋ ๋ฐ์ดํฐ๋ฅผ
ํ ๊ณณ์์ ๊ด๋ฆฌํ๋ ์ ์ญ ์ ์ฅ์๋ผ๊ณ ๋ณด๋ฉด ๋ผ์!

Provide/Inject๋ ๋น๊ตํ๋ฉด ์ด๋ฐ ์ฐจ์ด๊ฐ ์์ด์:
| ์ปดํฌ๋ํธ ๊ฒฐํฉ | ๊ฐํ๊ฒ ๊ฒฐํฉ | ์์ ๋ ๋ฆฝ |
| ๊ณต์ ๋ฒ์ | ํ์ ์ปดํฌ๋ํธ๋ง | ์ฑ ์ ์ฒด |
| ๋ชจ๋ํ | ์ด๋ ค์ | ์คํ ์ด ๋จ์๋ก ์ฝ๊ฒ |
| ๋ฉ๋ชจ๋ฆฌ ํจ์จ | ํญ์ ๋ฉ๋ชจ๋ฆฌ ์์ฃผ | ํ์ํ ๋ ์์ฑ |
Pinia Store ๋ง๋ค๊ธฐ (defineStore)

์คํ ์ด๋ src/stores ํด๋ ์์ ๋ง๋๋ ๊ฒ ๊ด๋ก์์.
// stores/todoStore.js
import { defineStore } from 'pinia'
import { reactive, computed } from 'vue'
export const useTodoStore = defineStore('todo', () => {
// State โ ๋ฐ์ํ ์ํ ๋ฐ์ดํฐ
const state = reactive({
todoList: [],
isLoading: false,
})
// Getter โ ์ฝ๊ธฐ ์ ์ฉ ๋
ธ์ถ
const todoList = computed(() => state.todoList)
const isLoading = computed(() => state.isLoading)
const doneCount = computed(() =>
state.todoList.filter(todo => todo.done). length
)
// Action โ ์ํ๋ฅผ ์์ ํ๋ ํจ์
function addTodo(todo) {
state.todoList.push(todo)
}
function deleteTodo(id) {
state.todoList = state.todoList.filter(t => t.id!== id)
}
function toggleDone(id) {
const todo = state.todoList.find(t => t.id === id)
if (todo) todo.done =! todo.done
}
// ์ธ๋ถ์ ๋
ธ์ถํ ํญ๋ชฉ ๋ฐํ
return {
todoList, isLoading, doneCount,
addTodo, deleteTodo, toggleDone
}
})์ฌ๊ธฐ์ ์ ์ผ ์ค์ํ ํฌ์ธํธ!
state์์ฒด๋ ์ ๋ ๋ฐํํ์ง ์์์.computed๋ก ๊ฐ์ผ ์ฝ๊ธฐ ์ ์ฉ ๋ฒ์ ๋ง ๋
ธ์ถํด์
์ธ๋ถ์์ ์ง์ ์์ ํ๋ ๊ฑธ ๋ง์์ผ ํฉ๋๋ค.
์ปดํฌ๋ํธ์์ ์คํ ์ด ์ฌ์ฉํ๊ธฐ
<script setup>
import { computed } from 'vue'
import { useTodoStore } from '@/stores/todoStore'
const store = useTodoStore()
// Action ํจ์๋ ๋ถํดํ ๋น OK
const { addTodo, deleteTodo, toggleDone } = store
// ์ฐธ์กฐ ํ์
(๋ฐฐ์ด)๋ ๋ถํดํ ๋น OK โ ๋ฐ์์ฑ ์ ์ง๋จ
const { todoList } = store
// ์์ ํ์
(์ซ์)์ ๋ฐ๋์ computed๋ก!
const doneCount = computed(() => store.doneCount)
</script>
<template>
<div>
<p> ์๋ฃ๋ ํ ์ผ: {{ doneCount }}</p>
<ul>
<li v-for="todo in todoList" :key="todo.id">
{{ todo.title }}
<button @click="toggleDone(todo.id)">์๋ฃ</button>
<button @click="deleteTodo(todo.id)">์ญ์ </button>
</li>
</ul>
</div>
</template>
๊ฐ์ฅ ๋ง์ด ํ๋ ์ค์ โ ์์ ํ์ ๋ถํดํ ๋น
์ด๊ฑฐ ์ง์ง ์ค์ํด์ ๋ฐ๋ก ์ ๋ฆฌํด์.
์คํ ์ด์์ ๋ฐ์ดํฐ ๊บผ๋ผ ๋ ๊ตฌ์กฐ ๋ถํด ํ ๋น ํธํ๊ฒ ์ฐ๊ณ ์ถ์์์.
๊ทผ๋ฐ ์ซ์, ๋ฌธ์์ด, ๋ถ๋ฆฌ์ธ ๊ฐ์ ์์ ํ์
์ ๋ถํดํ ๋นํ๋ฉด ๋ฐ์์ฑ์ด ๊นจ์ ธ๋ฒ๋ ค์!
// ์์ ํ์
๋ถํดํ ๋น โ ๋ฐ์์ฑ ๊นจ์ง
const { doneCount } = store
// doneCount๊ฐ ๋ฐ๋์ด๋ ํ๋ฉด์ด ์ ๋ฐ๋!
// ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ
const doneCount = computed(() => store.doneCount)์ ์ด๋ฐ ์ผ์ด ์๊ธฐ๋๋ฉด
์์ ํ์
์ ๋ถํดํ ๋น ์ ๊ฐ์ด ๋ณต์ฌ๋ผ์.

๋ณต์ฌ๋ ๊ฐ์ ์๋ณธ ์คํ ์ด๋ ์ฐ๊ฒฐ์ด ๋๊ฒจ์ ๋ฐ์์ฑ์ด ์ฌ๋ผ์ง๊ฑฐ๋ ์.
๋ฐ๋ฉด ๋ฐฐ์ดยท๊ฐ์ฒด ๊ฐ์ ์ฐธ์กฐ ํ์
์ ์ฐธ์กฐ๊ฐ ๋ณต์ฌ๋๊ธฐ ๋๋ฌธ์
์๋ณธ์ด๋ ์ฐ๊ฒฐ์ด ์ ์ง๋ผ์ ๋ฐ์์ฑ์ด ์ด์์์ด์.
| ํ์ | ๋ถํดํ ๋น | ๊ถ์ฅ ๋ฐฉ๋ฒ |
|---|---|---|
| number, string, boolean | ๋ฐ์์ฑ ๊นจ์ง | computed(() => store.value) |
| Array, Object | ๋ฐ์์ฑ ์ ์ง | ๋ถํดํ ๋น ๊ฐ๋ฅ |
| Function (Action) | ๋ฌธ์ ์์ | ๋ถํดํ ๋น ๊ฐ๋ฅ |
์๋ก๊ณ ์นจ ํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ ธ์ โ Local Storage ์ฐ๋
Pinia ์ํ๋ ๋ฉ๋ชจ๋ฆฌ์๋ง ์์ด์
์๋ก๊ณ ์นจ ํ๋ฉด ์ด๊ธฐํ๋ผ์.
์๋ฒ ์์ด ๋ฐ์ดํฐ๋ฅผ ์ ์งํ๋ ค๋ฉด
Local Storage์ ์ ์ฅํด์ผ ํฉ๋๋ค!

function addTodo(todo) {
state.todoList.push(todo)
syncStorage() // ์ํ ๋ณ๊ฒฝํ ๋๋ง๋ค ์ ์ฅ
}
function deleteTodo(id) {
state.todoList = state.todoList.filter(t => t.id !== id)
syncStorage()
}
// ๋ก์ปฌ ์คํ ๋ฆฌ์ง์ ์ ์ฅ (๋ฌธ์์ด๋ก ์ง๋ ฌํ)
function syncStorage() {
localStorage.setItem('todos', JSON.stringify(state.todoList))
}
// ์ฑ ์์ํ ๋ ๋ก์ปฌ ์คํ ๋ฆฌ์ง์์ ๋ณต์
function loadFromStorage() {
const saved = localStorage.getItem('todos')
if (saved) state.todoList = JSON.parse(saved)
}Local Storage๋ ๋ฌธ์์ด๋ง ์ ์ฅํ ์ ์์ด์JSON.stringify()๋ก ์ ์ฅํ๊ณ JSON.parse()๋ก ๊บผ๋ด์ผ ํด์!
์ํคํ ์ฒ ๊ณ ๋ฏผ โ ๋จ์ผ ์ฑ ์ ์์น (SRP)
์คํ ์ด ์์ ์๋ฒ ํต์ ์ฝ๋๊น์ง ๋ฃ์ผ๋ฉด ํธํ๊ธด ํ๋ฐ,
์ด๋ฌ๋ฉด Pinia ์ฑ
์์ด ๋ ๊ฐ๊ฐ ๋ผ๋ฒ๋ ค์.

- ์ํ ๊ด๋ฆฌ (์๋ Pinia ์ญํ )
- ์๋ฒ ํต์ (์ถ๊ฐ๋ ์ญํ )
๋จ์ผ ์ฑ ์ ์์น(SRP)
โํ๋์ ๋ชจ๋์ ํ๋์ ์ด์ ๋ก๋ง ์์ ๋์ด์ผ ํ๋ค.โ
API URL์ด ๋ฐ๋์ด๋, ์ํ ๊ตฌ์กฐ๊ฐ ๋ฐ๋์ด๋
๋ ๋ค ์คํ ์ด๋ฅผ ์์ ํด์ผ ํ๋ ์ํฉ์ด ์๊ธฐ๊ฑฐ๋ ์.
๊ทธ๋์ ํต์ ์ฝ๋๋ ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ ์ข์์!
// ์คํ ์ด๊ฐ ํต์ ๊น์ง ๋ด๋น โ SRP ์๋ฐ
async function fetchTodos() {
const res = await fetch('https://api.example.com/todos')
state.todoList = await res.json()
}
// API๋ ๋ณ๋ ํ์ผ๋ก ๋ถ๋ฆฌ
// api/todoApi.js โ ํต์ ๋ง ๋ด๋น
export const getTodos = () =>
fetch('https://api.example.com/todos').then(r => r.json())
// stores/todoStore.js โ ์ํ ๊ด๋ฆฌ๋ง ๋ด๋น
import { getTodos } from '@/api/todoApi'
async function fetchTodos() {
state.isLoading = true
state.todoList = await getTodos() // ํธ์ถ๋ง!
state.isLoading = false
}์ด๋ ๊ฒ ํ๋ฉด
- API ์ฃผ์ ๋ฐ๋๋ฉด โ
todoApi.js๋ง ์์ - ์ํ ๊ตฌ์กฐ ๋ฐ๋๋ฉด โ
todoStore.js๋ง ์์
์์ ์ด์ ๊ฐ ๋ฑ ํ๋์ฉ์ด ๋๋ ๊ฑฐ์์ ๐
๋ง๋ฌด๋ฆฌ
๋ณต์ตํ๋ฉด์ ์ ๋ฆฌํ๋ค ๋ณด๋๊น
์์
๋ ํ๋ ค๋ค์๋ ๋ถ๋ถ๋ค์ด ์ด์ ์ผ ์ ๋๋ก ์ดํด๋์ด์.
์ค์ผ๋ ํค ํ๋ก์ ํธ์์ Pinia ์ค์ ๋ก ์จ๋ณด๋ฉด์
๋ ์ตํ๋ด์ผ๊ฒ ์ต๋๋ค ๐ช
๊ฐ์ ๋ด์ฉ์ผ๋ก ํท๊ฐ๋ฆฌ์
จ๋ ๋ถ๋ค๊ป ๋์์ด ๋์ผ๋ฉด ์ข๊ฒ ์ด์!
๋ค์ ํฌ์คํ
์์ ๋ดฌ์ ๐