前端學(xué)習(xí)12 pinia 和 vuex 狀態(tài)管理
在現(xiàn)代前端開發(fā)中,狀態(tài)管理是一個(gè)至關(guān)重要的方面。尤其是在大型應(yīng)用中,如何高效、清晰地管理狀態(tài)不僅影響著代碼的可讀性和可維護(hù)性,還對應(yīng)用的性能有直接的影響。在 Vue3 中,Vuex 和 Pinia 是兩種主要的狀態(tài)管理庫,這兩者各有不同的設(shè)計(jì)理念和使用方式。
1.vuex
Vuex 是 Vue.js 官方的狀態(tài)管理庫。它采用了 Flux 的思想,提供了一個(gè)集中式存儲(chǔ),允許組件以不同的方式共享狀態(tài)。Vuex 的核心概念包括 State、Getters、Mutations 和 Actions。
其中:
1.State: 應(yīng)用的狀態(tài)存儲(chǔ)。
2.Getters: 類似于計(jì)算屬性,用于計(jì)算基于狀態(tài)的派生狀態(tài)。
3.Mutations: 處理狀態(tài)的唯一方式,直接修改狀態(tài)。
4.Actions: 進(jìn)行異步操作,并提交 Mutations。
5.modules:進(jìn)行劃分模塊。
vuex示例代碼:
// store.js
import { createStore } from 'vuex';
const store = createStore({
state: {
//狀態(tài)的存儲(chǔ)
count: 0,
},
getters: {
//計(jì)算其中的派生元素
doubleCount(state) {
return state.count * 2;
},
},
mutations: {
//定義其中的操作
increment(state) {
state.count++;
},
},
actions: {
//進(jìn)行異步操作,并提交 Mutations。
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
},
},
});
export default store;
使用vuex:
<template>
<div>
<p>Count: {{ count }}</p>
<p>Double Count: {{ doubleCount }}</p>
<button @click="increment">Increment</button>
<button @click="incrementAsync">Increment Async</button>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from 'vuex';
export default {
computed: {
...mapState(['count']),
...mapGetters(['doubleCount']),
},
methods: {
...mapActions(['increment', 'incrementAsync']),
},
};
</script>
2.pinia
Pinia 是一個(gè)新興的狀態(tài)管理庫,也是 Vue.js 的官方推薦替代方案。它為 Vue 3 提供了一種更簡單、更具靈活性的狀態(tài)管理方式,與 Vuex 相比,Pinia 在設(shè)計(jì)上更現(xiàn)代化,支持 Composition API,使得開發(fā)者在使用時(shí)更加方便。
其中:
Store: 狀態(tài)存儲(chǔ)的基本單位,通過建立一個(gè)或多個(gè) Store 來管理狀態(tài)。這是與vuex最主要的區(qū)別。
State: 用于保存應(yīng)用的響應(yīng)式狀態(tài)。
Getters: 計(jì)算屬性的延伸,基于狀態(tài)計(jì)算派生值。
Actions: 包含了執(zhí)行異步操作的行為和直接修改狀態(tài)的方法。
3.pinia的使用
3.1 piniad的創(chuàng)建
import { createApp,h } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const app = createApp(App)
app.use(createPinia())
3.2 pinia 定義store
在深入研究核心概念之前,我們需要知道 Pinia 是使用 defineStore() 定義的,并且它需要一個(gè)唯一的 name 作為第一個(gè)參數(shù)傳遞: name(也稱為id)是必需的,Pinia使用 name 參數(shù)將 Store 連接到 devtools。
將返回的函數(shù)命名為 use…
是一種跨組件的約定,使其用法規(guī)范化。
defineStore(name,options)
- name: 必傳,類型
string
- options:{}
import { defineStore } from 'pinia'
// useStore可以是任何類似useUser、useCart的東西
// 第一個(gè)參數(shù)是應(yīng)用程序中 Store 的唯一id
export const useStore = defineStore('main', {
// state: () => ({ count: 0 }),
state:()=>{
return {
// 所有這些屬性都將自動(dòng)推斷其數(shù)據(jù)類型
items: [],
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
},
getters: {
doubleCount: (state) => state.counter * 2,
//doubleCount(state){
// console.log(this,'想要在getter中獲取該store的其他內(nèi)容則不能用箭頭函數(shù),')
// return state.counter * 2
//},
},
actions: {
increment(num,test1,test2) {
console.log(num,test1,test2)
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
}
})
3.3 使用 Store
我們之所以聲明store,是因?yàn)樵?code>setup()內(nèi)部調(diào)用useStore()
之前不會(huì)創(chuàng)建存儲(chǔ)。
<template>
<p>Double count is {{ store.doubleCount }}</p>
</template>
<script>
import { mapState } from 'pinia'
import { useStore} from '@/stores/counter'
export default {
setup() {
const store = useStore()
store.counter++
store.$patch({ // 除了直接用store.counter++改變store之外,您還可以調(diào)用該$patch方法。state它允許您對部分對象同時(shí)應(yīng)用多個(gè)更改:
counter: store.counter + 1,
name: 'Abalam',
})
store.$patch((state) => { // $patch 方法還接受一個(gè)函數(shù),用于應(yīng)對復(fù)雜數(shù)據(jù)的修改過程
state.items.push({ name: 'shoes', quantity: 1 })
state.isAdmin = false
})
store.increment(9,'測試多參數(shù)1','測試2') // 調(diào)用 actions 并傳入?yún)?shù)
store.randomizeCounter() // 調(diào)用 actions
return {
// 您可以返回整個(gè)store實(shí)例以在模板中使用它
store,
}
},
computed: {
storeCounter() {
return this.store.counter * 3
},
// ...mapState(useCounterStore, ['counter']) // 沒有 setup 的時(shí)候才使用這方式
},
}
</script>
4.Vuex vs Pinia
現(xiàn)在我們來比較 Vuex 和 Pinia 的優(yōu)缺點(diǎn)。
4.1 API 和易用性
Vuex:
采用認(rèn)證的 Flux 風(fēng)格,有一定的學(xué)習(xí)曲線,需要掌握多個(gè)概念(狀態(tài)、getter、mutation、action)。對于小型應(yīng)用來說,可能會(huì)顯得過于復(fù)雜。
Pinia:
設(shè)計(jì)更為簡單,結(jié)合了 Composition API,讓開發(fā)者能夠更直觀地管理狀態(tài)。尤其是 Vue 3 的 Setup 語法糖,使用更加直觀。
4.2 響應(yīng)式
Vuex: 響應(yīng)式總是要依賴于 Vue 的響應(yīng)式系統(tǒng),并且有多種約定(例如 Mutation),使用中需要更小心。
Pinia:
完全基于 Vue 3 的響應(yīng)式系統(tǒng),狀態(tài)變化后組件自動(dòng)更新,無需額外的處理。
#前端學(xué)習(xí)#