###### tags: `Vue` `pinia`
{%hackmd BJrTq20hE %}
# Vue店商網頁-如何使用Pinia
## 什麼是Pinia?
首先pinia是一款Vue所使用的狀態管理套件,可以理解為先把資料放在一個倉庫,當不同的component要使用的時候再去倉庫拿資料。這樣子的好處是,可以不用把資料傳來傳去,可以取代prop、emit、provide、injection這些方法,還有Mitt這個套件。
## 安裝Pinia
在終端機,專案所地方輸入npm install pinia,如下圖

## 開始使用Pinia
### 1.在main.js中架設環境,以下為範例程式碼。
```javascript=
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)
app.mount('#app')
```
### 2.在src下建立stores資料夾,並且新增一個新的.js檔
如下圖

### 3.pinia-store的內容
```javascript=
import { defineStore } from 'pinia'
export default defineStore('自訂名稱', {
state: () => {
return {
counter: 0,
}
},
getters: {
doubleCount: (state) => state.counter * 2,
},
actions: {
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
}
}
}
```
其中的state與data一樣,getters與computed一樣,actions與methods相同,可以注意到在上面例子第13行中仍用this.counter
### 4.import Pinia的store (option-API)
在想要使用Pinia的component或是page中import如下
```javascript=
import { mapState, mapAction} from 'pinia'
import 自訂名稱 from '@/stores/檔名'
export default {
data () {
return {
}
},
// 在computed引入store的state與getters
computed: {
...mapState(自訂名稱, ['counter', 'doubleCount'])
},
// 在methods引入store的actions
methods: {
...mapActions(自訂名稱, ['randomizeCounter'])
},
// 所import進來的函式與變數都當成data與methods內已有的東西使用。
mounted () {
console.log(this.counter)
console.log(this.doubleCounter)
this.randomizeCounter()
}
}
```
### 4.import Pinia的store (composition-API)待補
### 5.store使用其他store的state與actions
以下範例為store cart 要使用 toast的action
store toast
```javascript=
import { defineStore } from 'pinia'
export default defineStore('toastStore') {
state: () => ({
notification: []
}),
actions: {
addMessage (message) {
this.notification.push(message)
setTimeout(() => {
this.notification.shift()
}, 5000)
}
}
```
store cart
```javascript=
import { defineStore } from 'pinia'
import axios from 'axios'
import toastStore from '@/stores/toast'
// 把toastStore最為函數執行
const toast = toastStore()
export default defineStore('cartStore') {
state: () => ({
cartData: [],
cartLength: 0,
}),
actions: {
deleteCart (id, title) {
this.isCartLoading = true
axios.delete(`${process.env.VUE_APP_API}/api/${process.env.VUE_APP_PATH}/cart/${id}`).then((res) => {
this.getCart()
// 直接使用toast內的addMessage,另外state與getter也是一樣的使用方式toast.xxx
toast.addMessage(
{
title: '刪除購物車結果',
style: 'success',
content: title + res.data.message
})
this.isCartLoading = false
}).catch((err) => {
console.dir(err.response.data.message)
toast.addMessage(
{
title: '刪除購物車結果',
style: 'danger',
content: err.response.data.message
})
})
}}
}
```
參考資料
---
[Pinia](https://pinia.vuejs.org/)