Post

13장: Pinia를 이용한 상태 관리

13장: Pinia를 이용한 상태 관리

13장: Pinia를 이용한 상태 관리

이 장에서는 Pinia를 사용해 Vue 애플리케이션의 상태를 관리하는 방법을 초급 개발자向け로 설명합니다. 각 주제에는 간단한 Vue 코드 예시와 요약이 포함됩니다.

13.1 Pinia란?

1
2
3
4
5
6
7
<script>
import { defineStore } from 'pinia';

export const useStore = defineStore('main', {
  state: () => ({ count: 0 })
});
</script>

요약: Pinia는 Vue의 간단하고 직관적인 상태 관리 라이브러리입니다.

13.2 Pinia 아키텍처와 구성 요소

13.2.1 Pinia 아키텍처

1
2
3
4
5
6
7
8
<script>
import { defineStore } from 'pinia';

export const useStore = defineStore('main', {
  state: () => ({ data: '' }),
  actions: { setData(value) { this.data = value; } }
});
</script>

요약: Pinia는 스토어를 통해 상태와 로직을 중앙 관리합니다.

13.2.2 스토어 정의

1
2
3
4
5
6
7
8
<script>
import { defineStore } from 'pinia';

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: { increment() { this.count++; } }
});
</script>

요약: 스토어는 상태와 액션을 정의하는 단위입니다.

13.2.3 Pinia를 사용하도록 Vue 애플리케이션 인스턴스 설정

1
2
3
4
5
6
7
8
9
<script>
import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';

const app = createApp(App);
app.use(createPinia());
app.mount('#app');
</script>

요약: Pinia는 Vue 앱에 플러그인으로 설치됩니다.

13.2.4 컴포넌트에서 스토어 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <div></div>
</template>
<script>
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    const counter = useCounterStore();
    return { counter };
  }
};
</script>

요약: 컴포넌트는 스토어를 호출해 상태를 사용합니다.

13.3 간단한 Pinia 예제 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <button @click="counter.increment">Count: </button>
</template>
<script>
import { useCounterStore } from '@/stores/counter';

export default {
  setup() {
    const counter = useCounterStore();
    return { counter };
  }
};
</script>

요약: Pinia로 간단한 카운터를 구현할 수 있습니다.

13.4 todolist-app-router 예제에 Pinia 적용하기

13.4.1 기존 예제 구조 검토

1
2
3
4
5
6
7
8
9
10
<template>
  <div>TodoList App</div>
</template>
<script>
export default {
  mounted() {
    console.log('기존 Todo 앱 로드');
  }
};
</script>

요약: 기존 앱 구조를 확인해 Pinia를 적용합니다.

13.4.2 백엔드 API 서버 실행

1
2
3
4
5
6
7
8
9
<script>
import axios from 'axios';

export default {
  mounted() {
    axios.get('http://localhost:3000/todos');
  }
};
</script>

요약: 백엔드 API로 데이터를 가져옵니다.

13.4.3 기초 작업

1
2
3
4
5
6
7
8
9
10
<script>
import { createPinia } from 'pinia';

export default {
  setup() {
    const pinia = createPinia();
    return { pinia };
  }
};
</script>

요약: Pinia를 프로젝트에 초기 설정합니다.

13.4.4 스토어 작성

1
2
3
4
5
6
7
8
<script>
import { defineStore } from 'pinia';

export const useTodoStore = defineStore('todo', {
  state: () => ({ todos: [] }),
  actions: { addTodo(todo) { this.todos.push(todo); } }
});
</script>

요약: Todo 데이터를 관리하는 스토어를 정의합니다.

13.4.5 App 컴포넌트 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <router-view />
</template>
<script>
import { useTodoStore } from '@/stores/todo';

export default {
  setup() {
    const todoStore = useTodoStore();
    return { todoStore };
  }
};
</script>

요약: App 컴포넌트에서 스토어를 활용합니다.

13.4.6 TodoList, TodoItem 컴포넌트 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <div v-for="todo in todoStore.todos" :key="todo.id"></div>
</template>
<script>
import { useTodoStore } from '@/stores/todo';

export default {
  setup() {
    const todoStore = useTodoStore();
    return { todoStore };
  }
};
</script>

요약: TodoList와 TodoItem에서 스토어 데이터를 표시합니다.

13.4.7 AddTodo, EditTodo 컴포넌트 변경

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <input v-model="newTodo" @keyup.enter="todoStore.addTodo(newTodo)" />
</template>
<script>
import { useTodoStore } from '@/stores/todo';

export default {
  setup() {
    const todoStore = useTodoStore();
    return { todoStore, newTodo: '' };
  }
};
</script>

요약: AddTodo와 EditTodo에서 스토어로 작업을 처리합니다.

13.5 마무리

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
  <div>Pinia로 Todo 앱 완료!</div>
</template>
<script>
import { useTodoStore } from '@/stores/todo';

export default {
  setup() {
    const todoStore = useTodoStore();
    return { todoStore };
  }
};
</script>

요약: Pinia로 상태 관리를 간소화했습니다.

This post is licensed under CC BY 4.0 by the author.