본문 바로가기

Vue

Vue 상태관리 - Pinia

State Management

: 상태 관리

- vue 컴포넌트는 이미 반응형 상태를 관리하고 있음

( 상태 === 데이터)

컴포넌트 구조의 단순화

컴포넌트 구조의 단순화

상태(State)

: 기본 데이터

뷰(View)

: 상태를 선언적으로 매핑하여 시각화

(template에 넣어 상태를 시각화)

기능(Actions)

: 뷰에서 사용자 입력으로 반응적으로 상태를 변경할 수 있게 정의된 동작

>> (기능>상태>뷰>기능) "단방향 데이터 흐름"의 간단한 표현

 

- "여러 컴포넌트가 상태를 공유할 때" 단순성이 무너짐

> 각 컴포넌트의 공유 상태를 전역에서 참조가능한 저장소에서 관리

> Vue의 공식 상태 관리 라이브러리 === "Pinia"

 

Pinia

Pinia 라이브러리 추가

- vue 프로젝트 생성 시 stores 폴더 신규 생성

Pinia 구성 요소

Pinia 구성 요소

1. store

- 중앙 저장소

- 모든 컴포넌트가 공유하는 상태, 기능 등이 작성됨

- defineStore()의 반환 값의 이름은 use, store를 사용하는 것을 권장

- defineStore()의 첫 번째 인자는 store의 고유 ID

2. state

- 반응형 상태(데이터)

- 각 컴포넌트 깊이에 관계 없이 store 인스턴스로 접근하여 읽고 쓰기 가능

- ref() === state

3. getters

- 계산된 값

- state와 마찬가지로 직접 접근 가능

- computed() === getters

4. actions

- 메서드

- state와 마찬가지로 직접 접근 및 호출 가능

- getters와 달리 state 조작, 비동기, API 호출이나 다른 로직을 진행 가능

- function() === actions

 

반환 값

- pinia의 상태들을 사용하려면 반드시 반환해야함

> store에서는 private한 상태 속성을 가지지 않음

 

추가 구성요소 : plugin

- 애플리케이션의 상태 관리에 필요한 추가 기능을 제공하거나 확장하는 도구나 모듈

- 상태 관리에 용이

 

>> Pinia는 store라는 저장소를 가짐

>> store는 state, getters, actions로 이루어지며

>> 각각 ref(), computed(), function()과 동일함

 


Pinia를 활용한 Todo 프로젝트 구현

- Todo CRUD 구현

- Todo 개수 계산

-- 완료된 Todo 개수

 

컴포넌트 구성

실습 - 컴포넌트 구성

사전준비

1. 초기 생성된 컴포넌트, src/assets 내부 파일, main.js에서 assets import 모두 삭제

2. components/TodoListItem.vue 컴포넌트 생성

3. components/TodoList.vue 컴포넌트 생성

  - TodoListItem 컴포넌트 등록

4. components/TodoForm.vue 컴포넌트 생성

5. App 컴포넌트에 TodoList, TodoForm 컴포넌트 등록

3. TodoList 컴포넌트 생성
5. App에 해당 컴포넌트 등록

READ(Todo 조회)

1. store에 임시 todos 목록 state를 정의

2. todos state를 참조 , 하위 컴포넌트(TodoListItem)을 반복하며 개별 todo를 props로 전달

3. props 정의

ref(리액티브 함수)로 정의하면 오류 발생

∵ id 자체가 ref 객체로 인식되기에 이후 id.value 변수로 접근해야하므로

> 코드 수정

1. 임시 todos 목록 state를 정의
2. state를 참조, 개별 todo를 props로 전달
3. props 정의

 

CREATE(Todo 생성)

1. todos 목록에 todo를 생성 및 추가하는 addTodo 액션 정의

2. TodoForm에서 실시간으로 입력되는 사용자 데이터를 양방향 바인딩 > 반응형 변수로 할당

3. submit 이벤트가 발생 했을 때 사용자 입력 텍스트를 인자로 전달

  - store에 정의한 addTodo 액션 메서드를 호출

4. form 요소를 선택해 todo 입력 후 input 데이터 초기화 할 수 있게 처리

1. addTodo 액션 정의 , 반환 값 추가
2,3,4 . todoText 정의, submit이 발생할 때 addTodo 호출, input 초기화

 

DELETE(todo 삭제)

1. todos 목록에서 특정 todo를 삭제하는 deleteTodo 액션 정의

  - 기능이 구현되는지 확인하기 위해 console.log로 처음에 작성

2. 각 todo에 삭제 버튼 작성, 버튼을 클릭할 때 선택된 todo의 id를 인자로 전달해 deleteTodo 호출

3. 전달받은 todo의 id로 todo의 인덱스 구함, 특정 인덱스 todo를 삭제 후 todos 재설정

2. 삭제 버튼 작성, 버튼을 클릭할 때 deleteTodo 호출
3. todo.id로 todo의 인덱스를 찾고 삭제

 

UPDATE(Todo 수정)

* 각 todo 상태의 isDone 속성 변경 > todo의 완료 유무 처리

* 완료된 todo에 취소선 스타일 적용

1. todos 목록에서 특정 todo의 isDone 속성을 변경하는 updateTodo 액션 정의

2. todd 내용을 클릭하면 todo의 id를 인자로 전달 > updateTodo 메서드 호출

3. 전달받은 todoId로 동일 todo를 목록에서 검색, 일치하는 isDone 속성 값을 반대로 재할당 후 새로운 todo 반환

4. todo 객체의 isDone 속성 값에 따라 스타일 바인딩 적용

2,4. todo.id로 updateTodo 호출, isDone 값에 따라 스타일 바인딩 적용
3. 전달받은 todo.id로 동일 todo 검색 > isDone 값을 반대로 재할당 후 todo 반환

5. 결과 확인

5. 결과 확인

COUNTING(완료된 todo 개수 계산)

1. doneTodosCount 정의 (getters)

2. App에 doneTodosCount 작성

1. doneTodosCount 정의
2. useCounterStore 호출 및 doneTodosCount 작성

 

Local Storage

: 브라우저 내에 key-value 쌍을 저장하는 웹 스토리지 객체

- 페이지를 새로고침하고 브라우저를 다시 실행해도 데이터 유지

- 네트워크 요청 시 서버로 전송 X

- 필요 데이터를 클라이언트가 보관 > 성능 향상, UX 개선

pinia-plugin-persistedstate

- 웹 애플리케이션의 상태(state)를 브라우저의 local storage나 session storage에 영구 저장 및 복원 기능 제공

1. 설치 및 등록

$ npm i pinia-plugin-persistedstate
// main.js

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()

pinia.use(piniaPluginPersistedstate)
app.use(pinia)
// stores/counter.js
// defineStore()의 3번째 인자로 객체 추가
export const useCounterStore = defineStore('counter', () => {
	...
	return {...}
}, { persist: true })

 

- 모든 데이터를 store에서 관리할 필요는 없음

-- pass props, emit event를 함께 사용