簡介
Pinia是Vuex的升級版逛尚,使用比Vuex更加簡單方便,同時支持Vue2.x和Vue3.x。Pinia是Vue的專屬狀態(tài)管理庫雪猪,它允許你跨組件和頁面共享狀態(tài)。簡單理解就是如果你有需要全組件都要共享訪問和操作的數(shù)據(jù)起愈,那么就用Pinia只恨。
使用入門
安裝包
npm install pinia
配置
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
以上是適用于Vue3的译仗,如果是Vue2還需要安裝一個插件,并在應(yīng)用的根部注入創(chuàng)建的pinia
:
import {defineStore} from 'pinia'
/**
* 定義并到處容器
* 參數(shù)1:容器的ID官觅,必須唯一纵菌,將來Pinia會把所有的容器掛載到根容器
* 參數(shù)2:選項對象
* 返回值:一個函數(shù),調(diào)用得到容器實例
*/
export const useCounterStore = defineStore('counter',{
/**
* 類似于組件的data休涤,用來存儲全局狀態(tài)的
* 1咱圆、必須是函數(shù):這樣是為了服務(wù)端渲染的時候避免交叉請求導致數(shù)據(jù)狀態(tài)的污染
* 2、必須是箭頭函數(shù)功氨,為了更好的TS類型推導
*/
state:() => {
return {
count:0
}
},
/**
* 類似于組件的computed序苏,用來封裝計算屬性,有緩存的功能
*/
getters:{
double:(state) => state.count * 2
},
/**
* 類似于組件的methods捷凄,封裝業(yè)務(wù)邏輯忱详,修改state
*/
actions:{
increment(){
this.count++
}
}
})
以上是展示的Option Store方式創(chuàng)建Store,還有一種就和setup函數(shù)類似的Setup Store創(chuàng)建方式:
坑點
- 不要直接解構(gòu)state跺涤,因為state原理就是使用reactive進行封裝匈睁,所以reactive有的缺點它也有(比如解構(gòu)后失去響應(yīng)性)。如果先使用解構(gòu)方式訪問桶错,Pinia提供了
storeToRefs()
- 不能在
actions
中定義箭頭函數(shù)软舌,this的指向會混亂。 -
getters
和computed
類似牛曹,對數(shù)據(jù)會有緩存佛点,沒有改變時多次調(diào)用都會調(diào)用緩存的數(shù)據(jù)。
使用
- state的基本使用
<script setup>
import { useCounterStore } from "../../store/index";
const mainstore = useCounterStore()
const handleChangeState = () => {
//方式一黎比,最簡單的方式
mainstore.count++
//方式二超营,需要修改多個數(shù)據(jù),建議使用$patch 批量更新(內(nèi)部有性能優(yōu)化)
mainstore.$patch({
count: mainstore.count + 1,
message:'changed info',
arr:[...mainstore.arr,66]
})
//方式三:$patch一個函數(shù),更好的批量更新方式
mainstore.$patch(state => {
state.count++
state.message = 'info3'
state.arr.push(99)
})
}
</script>
以上方法都可以放到actions
中做處理,同樣可以通過this.$patch
的方式批量操作狀態(tài)
- getters的使用
- actions的使用
類似
getters
阅虫,不同的是演闭,action可以是異步的,可以在里面await調(diào)用任何API颓帝,以及其他的action米碰。
訪問其他store上的action
- 訂閱Action(
store.$onAction()
)
可以通過
store.$Action()
來監(jiān)聽action和它們的結(jié)果。傳遞給它的回調(diào)函數(shù)會在action本身之前執(zhí)行购城。
after
表示在promise解決之后吕座,允許你在action解決后執(zhí)行一個回調(diào)函數(shù)。
onError
允許你在action拋出錯誤或reject時執(zhí)行一個回調(diào)函數(shù)瘪板。
這些函數(shù)對于追蹤運行時錯誤非常有用吴趴。
const unsubscribe = someStore.$onAction(
({
name, // action 名稱
store, // store 實例,類似 `someStore`
args, // 傳遞給 action 的參數(shù)數(shù)組
after, // 在 action 返回或解決后的鉤子
onError, // action 拋出或拒絕的鉤子
}) => {
// 為這個特定的 action 調(diào)用提供一個共享變量
const startTime = Date.now()
// 這將在執(zhí)行 "store "的 action 之前觸發(fā)侮攀。
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 這將在 action 成功并完全運行后觸發(fā)锣枝。
// 它等待著任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果 action 拋出或返回一個拒絕的 promise厢拭,這將觸發(fā)
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 手動刪除監(jiān)聽器
unsubscribe()
默認情況下,action訂閱器會被綁定到添加它們的組件上(如果store在組件的setup()
內(nèi))撇叁。這意味著供鸠,當組件被卸載時,它們將被自動刪除陨闹。如果你想在組件卸載時依舊保留它們回季,就將true作為第二個參數(shù)傳遞給action訂閱器,以便將其從當前組件中分離:
<script setup>
const someStore = useSomeStore()
// 此訂閱器即便在組件卸載之后仍會被保留
someStore.$onAction(callback, true)
</script>