Pinia
- 컴포넌트들 간의 데이터 전달은 Props / Emit을 통해 가능하다. 하지만 컴포넌트들이 많고 복잡해지면, 복잡성이 증가해 코드의 가독성 및 유지 보수가 힘들어진다.
상태관리
- 상태 관리(State Management)는 복잡한 웹 애플리케이션에서 데이터의 흐름과 상태를 효율적으로 관리하기 위한 개념이다.
- 애플리케이션의 상태는 사용자 인터페이스(UI)의 시점에서 보여지는 모든 것을 포함한 데이터의 집합이다.
- 상태관리를 통해 여러 컴포넌트 간에 상태를 공유하고 동기화할 수 있다.
Pinia
Pinia | The intuitive store for Vue.js
Intuitive, type safe, light and flexible Store for Vue
pinia.vuejs.org
- vue에서 사용 가능한 상태관리 라이브러리이다.
Store
- store는 데이터를 관리하는 공간이다.
- component에서 관리하던 data를 store에서 관리하게 되며, 각 component는 store에서 data를 꺼내어 사용한다.
- store에 저장되는 변수를 state라고 하며, state는 store 내부에 정의된 함수(actions)로만 변경 가능하도록 설계한다.
- 다음과 같은 형태로 관리하며,
- name은 store에서 관리할 데이터를 설명하는 이름으로 작성한다.
- 일반 변수 및 함수를 작성하듯 사용하며, 정의한 변수, 함수를 store가 return하여 component에서 활용할 수 있다.
export const useNameStore = defineStore('name', () => {
const value = ref('')
function func() {
// change value
}
return { value, func }
})
- MyComponent.vue에서의 변경사항을 App.vue에서 확인해보자.
- vue 프로젝트를 생성
$ npm create vite@latest .
- 모듈을 설치
$ npm install
$ npm i sass
- App.vue 수정 및 components/MyComponent.vue 생성
- App.vue
<template>
<div>
<h1>my App</h1>
<MyComponent />
</div>
</template>
<script setup>
import MyComponent from './components/MyComponent.vue';
</script>
<style lang="scss" scoped>
</style>
- components/MyComponent.vue
<template>
<div>
<h2>my Component</h2>
</div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
</style>
- pinia 설치
npm install pinia
- main.js 수정
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
- src/stores 폴더 및 src/stores/counter.js 생성
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function increment() {
count.value++
}
return { count, increment }
})
- App.vue 수정
- count를 보여준다
<template>
<div>
<h1>my App</h1>
<div>count : {{ counterStore.count }}</div>
<MyComponent />
</div>
</template>
<script setup>
import MyComponent from './components/MyComponent.vue';
import { useCounterStore } from './stores/counter'
const counterStore = useCounterStore();
</script>
- components/MyComponent.vue 수정
- increment에 대한 event를 만들어준다.
<template>
<div>
<h2>my Component</h2>
<button @click="counterStore.increment">클릭!</button>
</div>
</template>
<script setup>
import { useCounterStore } from '/src/stores/counter'
const counterStore = useCounterStore();
</script>
<style lang="scss" scoped>
</style>
[실습]
- 다음 구조를 참고하여, myComponent.vue에서의 입력값이 App.vue에서 보이도록 구현하시오.
- App.vue
<template>
<div>
<h1>my App</h1>
<div>text : {{ textStore.text }}</div>
<MyComponent />
</div>
</template>
<script setup>
import MyComponent from './components/MyComponent.vue';
import { useCounterStore } from './stores/counter'
import { useTextStore } from './stores/text'
const counterStore = useCounterStore()
const textStore = useTextStore()
</script>
<style lang="scss" scoped>
</style>
- MyComponent.vue
<template>
<div>
<h2>my Component</h2>
<input type="text" @input="onInput">
<button @click="counterStore.increment">클릭!</button>
</div>
</template>
<script setup>
import { useCounterStore } from '/src/stores/counter'
import { useTextStore } from '../stores/text';
const counterStore = useCounterStore()
const textStore = useTextStore()
function onInput(e){
// console.log(e.target.value)
textStore.setText(e.target.value)
}
</script>
<style lang="scss" scoped>
</style>
- stores/text.js
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useTextStore = defineStore('text', () => {
const text = ref('잘 들어갔니?')
function setText(data){
text.value = data
}
return { text, setText }
})
'Vue' 카테고리의 다른 글
Vue(Backend) : Django(Frontend) (0) | 2024.03.28 |
---|---|
Vue library : Vue Router (0) | 2024.03.28 |
Vue 실습(2) (0) | 2024.03.27 |
Vue : Component, Props, Emit (0) | 2024.03.27 |
Vue 실습(1) (0) | 2024.03.27 |