一、簡介
Pinia 是一個由 Vue.js 核心成員 Luy 帶頭開發的 Vuex 替代品,它基於 Vue 3 composition API 構建,提供了一種更加簡潔優雅的狀態管理方案。
相比於 Vuex,Pinia在以下幾個方面提供了顯著的改進:
- 支持 TypeScript
- 數據響應式更新更加優化
- 使用 composition API 來進行狀態管理編寫
- 提供了插件機制,易於擴展
- 支持多個 store 實例創建
二、安裝和基本使用
安裝 Pinia:
npm install pinia
在 Vue 3 的應用中,使用 createApp() 方法來創建實例:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
上述代碼中,我們使用 createPinia() 方法來創建一個名為 Pinia 的插件,同時將其安裝到 Vue 3 實例上,然後通過 app.mount() 來掛載應用。
接下來,來看一下如何在組件內部使用 Pinia 插件。
首先,需要定義一個 store 實例。
import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
count: 0
}),
actions: {
increment() {
++this.count
}
}
})
上面代碼中,我們使用 defineStore() 方法來定義一個名為 useCounterStore 的 store 實例,其中包含 state、mutations 和 actions 等屬性。
在使用 defineStore() 方法時,需要傳入一個配置對象,其中包含以下屬性:
id
: String 類型,用來唯一標識此 store 實例。state
: Function 類型,用來返回此 store 實例的狀態對象。actions
: Object 類型,包含多個用於更新狀態的方法。mutations
: Object 類型,包含多個用於更新狀態的方法。getters
: Object 類型,包含多個讀取狀態值的方法。actionsContext
: Object 類型,包含多個上下文相關的方法。mutationsContext
: Object 類型,包含多個上下文相關的方法。
接下來,通過 useStore() 方法來使用 store 實例:
import { useCounterStore } from './store'
export default {
setup() {
const store = useCounterStore()
const handleIncrement = () => {
store.increment()
}
return {
handleIncrement,
count: store.count
}
}
}
上面的代碼中,我們使用 useCounterStore() 來獲取 useCounterStore 這個 store 實例對象,並將其賦值給一個變數 store,接著通過調用 store 實例對象中的 increment 方法來更新 count 狀態值的值。
三、插件機制
在需要對 Pinia 進行擴展或者自定義時,可以使用 Pinia 提供的 plugin 機制來實現,插件可以為 Store 實例添加更多的能力和特性,如:日誌記錄、數據持久化等。
下面是一個使用插件的示例:
import { createPinia } from 'pinia'
import { Storage } from '@ionic/storage'
const storage = new Storage()
const store = createPinia()
store.use((pinia) => {
pinia.$onAction(({ type, payload }, state) => {
console.log(`Action ${type} with payload`, payload, `updated with state`, state)
})
pinia.$onMutation(({ type, payload }) => {
console.log(`Mutation ${type} with payload`, payload)
})
pinia.$subscribe((mutation, state) => {
storage.set(mutation.type, state)
})
pinia.$restore(({ type }) => {
return storage.get(type)
})
})
上述代碼中,我們使用 use() 方法來安裝插件,然後在回調函數內部對 Store 實例添加了四個功能:
- 使用 $onAction 方法來監聽 actions 的修改,並在控制台中輸出相關信息。
- 使用 $onMutation 方法來監聽 mutations 的修改,並在控制台中輸出相關信息。
- 使用 $subscribe 方法來監聽 state 的修改,並將修改後的數據進行持久化。
- 使用 $restore 方法來獲取持久化的數據並還原到 store 實例中。
四、多個實例的創建
Pinia 提供多個 Store 實例的創建方式,可以根據不同的需要創建不同的實例。
下面是一個多個實例同時運行的示例:
// file: store.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore({
id: 'counter',
state: () => ({
count: 0
}),
actions: {
increment() {
++this.count
}
}
})
export const useTodoStore = defineStore({
id: 'todo',
state: () => ({
todos: []
}),
actions: {
add(todo) {
this.todos.push(todo)
}
}
})
上述代碼中,我們分別定義了兩個 store 實例 useCounterStore 和 useTodoStore。
// file: main.js
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
import { useCounterStore } from './store'
const app1 = createApp(App)
const app2 = createApp(App)
app1.use(createPinia())
app2.use(createPinia())
const store1 = useCounterStore()
const store2 = useCounterStore()
app1.config.globalProperties.$store = store1
app2.config.globalProperties.$store = store2
app1.mount('#app1')
app2.mount('#app2')
上述代碼中,我們首先通過 createApp() 方法來創建兩個不同的 Vue 3 實例 app1 和 app2,接著分別為兩個實例都安裝了 Pinia,並聲明了兩個不同的 useCounterStore 實例對象 store1 和 store2,最後將 store 實例存放到每個實例的全局屬性中,最終通過 app1 和 app2 來分別將兩個實例掛載到不同的元素上。
五、總結
通過上述的介紹,可以看出 Pinia 是一個功能強大的狀態管理方案,它比 Vuex 更加簡單、直觀、靈活,是 Vue 3 開發中值得推薦的一款工具。
在使用 Pinia 時,需要注意以下幾點:
- 需要安裝插件才能夠實現更多的功能;
- 支持 TypeScript,需要進行類型約束;
- 使用 composition API 編寫狀態管理邏輯;
- 支持多個 Store 實例的創建。
原創文章,作者:MIVTC,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/370049.html