一、pinia 特點
- 體積小澈歉、性能好绢要、使用簡單、限制少
- 支持 Vue Devtools惠豺、模塊熱更新银还、服務(wù)端渲染、Vue2 和 Vue3
- 沒有 mutations洁墙,只有 state蛹疯、getters、actions(異步和同步都可)
二热监、pinia 安裝配置
- 安裝
npm install pinia -S
- 在 main.js 中注冊 pinia
import { createPinia } from 'pinia'
app.use(createPinia())
- 注意事項
1. pinia 的配置是模塊化的捺弦,通過 defineStore() 函數(shù)的參數(shù)來定義不同模塊,通過 import 導(dǎo)入的方式在組件中使用
2. 根據(jù) defineStore() 的參數(shù)不同:可以通過選項式的方式定義模塊store孝扛、也可以通過組合API的方式定義模塊store
3. 在組件中使用 store 中的state數(shù)據(jù)需要注意:store直接在模板中使用是響應(yīng)式的列吼,但是如果通過解構(gòu)的方式使用則不是響應(yīng)式的,
如果一定要解構(gòu)使用苦始,可以通過 storeToRefs(store) 函數(shù)對 store 進(jìn)行響應(yīng)式解構(gòu)
4. 在 pinia 中改變 state 的狀態(tài)寞钥,可以直接通過賦值的方式進(jìn)行改變,沒有vuex中只能通過commit修改的限制
5. 在組件中使用模塊store中 state 的數(shù)據(jù)時直接使用store.的方式陌选,而不是store.state.理郑,使用 getter 也是一樣直接 store.
6. 在組件中使用模塊store中 action 方法時直接使用既可,不需要使用模塊的名稱咨油,
因為我們在組件中使用import解構(gòu)導(dǎo)入store時香浩,已經(jīng)指定了模塊下的store
7. pinia 中的 getter 沒有緩存效果,相當(dāng)于調(diào)用函數(shù)臼勉,可傳入?yún)?shù)
三邻吭、pinia 通過選項方式配置 store
- 創(chuàng)建 src\stores\a.js 模塊配置文件
import { defineStore } from 'pinia'
export const aStore = defineStore({
id: 'a',
state: () => ({
a: 1,
oa: { a: 100 }
}),
getters: {
ca: (state) => {
return state.a * 2
}
},
actions: {
// actions 同步
SYNCA() {
this.a = this.a * 2
},
// actions 異步
async ASYNCA(params) {
const data = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
params ? resolve(params + 1) : reject(0)
}, 2000)
})
}
const getData = await data()
this.oa.a = this.oa.a * getData
// 如果有部分?jǐn)?shù)據(jù)沒有在state中定義,但是需要在組件中使用宴霸,也可以通過返回 promise 的方式異步處理
// return getData
}
}
})
- 在組件中使用
<template>
<div>
<h1>{{ useAStore.a }}</h1>
<h1>{{ oa.a }}</h1>
<h1>{{ ca }}</h1>
<button @click="setSYNCA">setSYNCA</button>
<button @click="setASYNCA">setASYNCA</button>
</div>
</template>
<script setup>
import { aStore } from '@/stores/a.js'
import { storeToRefs } from 'pinia'
const useAStore = aStore()
const { oa, ca } = storeToRefs(useAStore) // 響應(yīng)式解構(gòu)數(shù)據(jù)
const { SYNCA, ASYNCA } = useAStore
function setSYNCA() {
oa.value.a ++ // 在組件中囱晴,直接通過賦值改變 state
SYNCA(1)
}
function setASYNCA() {
ASYNCA(1)
// 如果在 action 中,返回了一個 promise 數(shù)據(jù)瓢谢,可以使用鏈?zhǔn)降姆绞将@取數(shù)據(jù)
// ASYNCA(1).then((res) => console.log(res)).catch((err) => console.log(err))
}
</script>
四畸写、pinia 通過組合 API 方式配置 store
- 創(chuàng)建 src\stores\a.js 模塊配置文件
import { ref, computed, reactive } from 'vue'
import { defineStore } from 'pinia'
export const aStore = defineStore('a', () => {
// state
const a = ref(1)
const oa = reactive({ a: 100 })
// getters
const ca = computed(() => a.value * 2)
// actions 同步
function SYNCA() {
a.value = a.value * 2
}
// actions 異步
async function ASYNCA(params) {
const data = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
params ? resolve(params + 1) : reject(0)
}, 2000)
})
}
const getData = await data()
oa.a = oa.a * getData
// 如果有部分?jǐn)?shù)據(jù)沒有在state中定義,但是需要在組件中使用氓扛,也可以通過返回 promise 的方式異步處理
// return getData
}
return { a, oa, ca, SYNCA, ASYNCA }
})
- 在組件中使用
<template>
<div>
<h1>{{ useAStore.a }}</h1>
<h1>{{ oa }}</h1>
<h1>{{ ca }}</h1>
<button @click="setSYNCA">setSYNCA</button>
<button @click="setASYNCA">setASYNCA</button>
</div>
</template>
<script setup>
import { aStore } from '@/stores/a.js'
import { storeToRefs } from 'pinia'
const useAStore = aStore()
const { oa, ca} = storeToRefs(useAStore) // 響應(yīng)式解構(gòu)數(shù)據(jù)
const { SYNCA, ASYNCA } = useAStore
function setSYNCA() {
oa.value.a ++ // 直接在組件中枯芬,通過賦值改變 state
SYNCA(1)
}
function setASYNCA() {
ASYNCA(1)
// 如果在 action 中,返回了一個 promise 數(shù)據(jù)采郎,可以使用鏈?zhǔn)降姆绞将@取數(shù)據(jù)
// ASYNCA(1).then((res) => console.log(res)).catch((err) => console.log(err))
}
</script>
五千所、pinia 特色 API
- 批量修改 store 中的 state
import { aStore } from '@/stores/a.js'
aStore.$patch((state) => {
state.items.push({ a: 100 })
state.hasChanged = true
})
- 整體替換 store 中的 state
import { aStore } from '@/stores/a.js'
aStore.$state = {
a: 1,
oa: { a: 100 }
}