상태 === 데이터
"단방향 데이터 흐름"의 간단한 표현
Vue의 공식 상태 관리 라이브러리 === "Pinia"

stores/counter.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
// store
export const useCounterStore = defineStore('counter', () => {
// state
const count = ref(0)
// getters
const doubleCount = computed(() => count.value * 2)
// actions
const increment = function () {
count.value++
}
// 반환값
return { count, doubleCount, increment }
})
defineStore()의 반환 값의 이름은 use와 store를 사용하는 것을 권장
defineStore()의 첫번째 인자는 애플리케이션 전체에 걸쳐 사용하는 store의 고유 ID
App.vue
js
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
// state 참조 및 변경
console.log(store.count)
const newNumber = store.count + 1
html
<template>
<div>
<p>state : {{ store.count }}</p>
</div>
</template>
App.vue
js
// getters 참조
console.log(store.doubleCount)
html
<template>
<div>
<p>getters : {{ store.doubleCount }}</p>
</div>
</template>
App.vue
js
// actions 호출
store.increment()
html
<template>
<div>
<button @click="store.increment()">+++</button>
</div>
</template>

import './assets/main.css'
TodoListItem.vue
<template>
<div>
TodoListItem
</div>
</template>
TodoList.vue
<template>
<div>
<TodoListItem />
</div>
</template>
<script setup>
import TodoListItem from '@/components/TodoListItem.vue'
</script>
TodoForm.vue
<template>
<div>
TodoForm
</div>
</template>
TodoList.vue
<template>
<div>
<h1>Todo Project</h1>
<TodoList />
<TodoForm />
</div>
</template>
<script setup>
import TodoForm from '@/components/TodoForm.vue'
import TodoList from '@/components/TodoList.vue'
</script>
store에 임시 todos 목록 state를 정의

store의 todos state를 참조
하위 컴포넌트인 TodoListItem을 반복하면서 개별 todo를 props로 전달


props 정의 후 데이터 출력 확인

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

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

submit 이벤트가 발생했을 때 사용자 입력 텍스트를 인자로 전달하여 store에 정의한 addTodo 액션 메서드를 호출

form 요소를 선택하여 todo 입력 후 input 데이터를 초기화할 수 있도록 처리

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

각 todo에 삭제 버튼을 작성
버튼을 클릭하면 선택된 todo의 id를 인자로 전달해 deleteTodo 메서드 호출

전달받은 todo의 id 값을 활용해 선택된 todo의 인덱스를 구함
특정 인덱스 todo를 삭제 후 todos 배열을 재설정

"각 todo 상태의 isDone 속성을 변경하여 todo의 완료 유무 처리하기"
완료된 todo에는 취소선 스타일 적용하기
todos 목록에서 특정 todo의 isDone 속성을 변경하는 updateTodo 액션 정의

todo 내용을 클릭하면 선택된 todo의 id를 인자로 전달해 updateTodo 메서드를 호출

전달받은 todo의 id값을 활용해 선택된 todo와 동일 todo를 목록에서 검색
일치하는 todo 데이터의 isDone 속성 값을 반대로 재할당 후 새로운 todo 목록 반환

todo 객채의 isDone 속성 값에 따라 스타일 바인딩 적용하기

todos 배열의 길이 값을 반환하는 함수 doneTodosCount 작성 (getters)

App 컴포넌트에서 doneTodosCount getter를 참조

설치
$ npm i pinia-plugin-persistedstate
등록


적용 결과 (개발자 도구 -> Application -> Local Storage)
결과적으로 적절한 상황에서 활용했을 때 Pinia 효용을 극대화할 수 있음