###### tags: `Vue` `pinia` {%hackmd BJrTq20hE %} # Vue店商網頁-如何使用Pinia ## 什麼是Pinia? 首先pinia是一款Vue所使用的狀態管理套件,可以理解為先把資料放在一個倉庫,當不同的component要使用的時候再去倉庫拿資料。這樣子的好處是,可以不用把資料傳來傳去,可以取代prop、emit、provide、injection這些方法,還有Mitt這個套件。 ## 安裝Pinia 在終端機,專案所地方輸入npm install pinia,如下圖 ![](https://i.imgur.com/FJOyd68.jpg) ## 開始使用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檔 如下圖 ![](https://i.imgur.com/pWddp4i.jpg) ### 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/)