Vue使用Pinia輕松實(shí)現(xiàn)狀態(tài)管理
前言
pinia,一個(gè)基于Vue3的狀態(tài)管理庫(kù),它可以幫助開(kāi)發(fā)人員管理Vue應(yīng)用程序的狀態(tài),Pinia使用Vue3的Composition API提供了更簡(jiǎn)單,靈活的狀態(tài)管理方式,通過(guò)創(chuàng)建store來(lái)管理應(yīng)用程序的狀態(tài),還提供了插件和工具來(lái)幫助開(kāi)發(fā)人員更輕松的使用它。
Pinia對(duì)比VueX
之前我們?cè)趘ue2的時(shí)候使用的狀態(tài)管理庫(kù)是VueX,在Vue3中想使用VueX,需要使用到VueX4版本,而在Vue3組合式API下設(shè)計(jì)了全新的狀態(tài)管理庫(kù):Vuex5,也就是Pinia(已經(jīng)被納入官方了)
那Pinia相比VueX有什么優(yōu)勢(shì)呢?

在當(dāng)時(shí)pinia的作者就作出了這么一個(gè)提案:
- pinia都支持在vue2和vue3中使用
- 在vuex想修改數(shù)據(jù)狀態(tài)需要mutations,而pinia去掉了mutations,只有state,getters和actions。修改數(shù)據(jù)狀態(tài)直接在actions里操作,pinia推崇使用類似于 JavaScript 對(duì)象的方式來(lái)更新?tīng)顟B(tài),即直接對(duì) state 進(jìn)行修改,可以減少代碼量,并且降低了出錯(cuò)的可能性
- pinia中沒(méi)有嵌套模塊,在vuex中我們可能會(huì)用到大量的模塊,一層套一層,使?fàn)顟B(tài)管理變得復(fù)雜,也有可能會(huì)造成命名沖突,在Composition API下pinia中可以定義多個(gè)store,然后將多個(gè)store組合在一起,變得更加靈活
- 完整的TypeScript支持,vuex對(duì)ts的類型檢查,類型推斷和泛型的支持都不太友好,模塊命名空間的支持也不夠完善
除此之外兩者的api都是相同的,使用的方式也是相同的,關(guān)于vuex的使用可以看看之前寫(xiě)的vuex文章
Pinia的使用
安裝pinia
使用pinia需要先安裝,可以通過(guò)yarn或者npm安裝
yarn add pinia
# or with npm
npm install pinia
在vue2中使用,你還需要安裝一個(gè)插件并pinia在應(yīng)用程序的根目錄注入創(chuàng)建的,如果vue版本<2.7,還需要安裝 composition api: @vue/composition-api

安裝完之后在入口文件引入pinia的createPinia方法并調(diào)用得到pinia的實(shí)例,然后掛載到vue實(shí)例上
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
//創(chuàng)建pinia實(shí)例
const pinia = createPinia();
const app = createApp(App);
//掛載到vue實(shí)例上
app.use(pinia);
app.mount("#app");定義store容器
在src目錄下創(chuàng)建store目錄來(lái)存放pinia容器相關(guān)代碼,在里面新建了一個(gè)index.ts文件,在index.ts文件里首先要定義一個(gè)容器,定義容器使用defineStore來(lái)定義,主要接收兩個(gè)參數(shù),一個(gè)是容器的名字(唯一),另一個(gè)是容器的對(duì)象,最后將容器導(dǎo)出,就可以在組件中使用了
import { defineStore } from "pinia";
export const useTestStore = defineStore("test", {
/**
* 類似組件中的data,存儲(chǔ)全局狀態(tài)
* 必須是箭頭函數(shù),避免數(shù)據(jù)狀態(tài)污染
*/
state: () => {
return {
message: "hello world",
count:0,
};
},
/**
* 類似組件中的computed
*/
getters: {},
/**
* 類似組件中的methods,封裝業(yè)務(wù)邏輯,修改state
*/
actions: {},
});在組件中導(dǎo)入并使用容器
state的使用
在組件中導(dǎo)入容器并且調(diào)用,得到容器的實(shí)例,就可以直接使用state里的數(shù)據(jù)或者在模板中展示
<script setup lang="ts">
import { useTestStore } from "./store";
const store = useTestStore();
</script>
<template>
<div>{{ store.message }}</div>
</template>
<style scoped>
</style>
也可以使用解構(gòu)的方式拿到和使用數(shù)據(jù),但是這樣拿到的數(shù)據(jù)不是響應(yīng)式的,修改的時(shí)候頁(yè)面上是不會(huì)發(fā)生變化的
<script setup lang="ts">
import { useTestStore } from "./store";
const store = useTestStore();
//解構(gòu)state
const { message, count } = store;
const countAdd = () => {
store.count++;
};
</script>
<template>
<div>
<div>{{ store.message }}</div>
<div>{{ store.count }}</div>
<hr />
<div>{{ "解構(gòu)后:" + message }}</div>
<div>{{ "解構(gòu)后:" + count }}</div>
<button @click="countAdd">count++</button>
</div>
</template>
<style scoped>
</style>
針對(duì)這種情況解決的辦法就是解構(gòu)的時(shí)候使用pinia的storeToRefs方法將實(shí)例包裹住,state里的數(shù)據(jù)就變成響應(yīng)式的了
import { storeToRefs } from "pinia";
//解構(gòu)state,對(duì)state里的數(shù)據(jù)做了reactive處理
const { message, count } = storeToRefs(store);
狀態(tài)的更新和actions的使用
在組件里修改state的狀態(tài)的時(shí)候有三種方式:
- 直接修改
- $patch直接修改
- $patch通過(guò)函數(shù)修改
const countAdd = () => {
// 直接修改
store.count++;
store.message = 'hello pinia'
// 修改多個(gè)數(shù)據(jù) $patch批量修改
store.$patch({
count: store.count + 1,
message: "hello pinia",
});
// $patch 函數(shù)(推薦)
store.$patch(state=>{
state.count++
state.message = "hello pinia"
})
};也可以通過(guò)actions處理,在actions定義一個(gè)方法,通過(guò)this訪問(wèn)當(dāng)前實(shí)例拿到state里的數(shù)據(jù),就像vue2的options API一樣在methods里拿data里的數(shù)據(jù)
// store
actions: {
handleChangeState() {
this.message = "hello pinia";
this.count++;
},
},
//component
const countAdd = () => {
store.handleChangeState();
};也可以在調(diào)用actions里的方法的時(shí)候傳遞參數(shù)
// store
actions: {
handleChangeState(num?: number) {
this.count += num ?? 0;
},
},
//component
const countAdd = () => {
store.handleChangeState(10);
};getters的使用
getters類似組件中的computed,接收一個(gè)state參數(shù),這個(gè)state就是容器里的state狀態(tài)對(duì)象,當(dāng)依賴的state發(fā)生變化的時(shí)候pinia就會(huì)自動(dòng)更新getters的值,而且getters具有默認(rèn)的緩存機(jī)制
如果一個(gè)getter所依賴的state沒(méi)有發(fā)生變化,那么就返回上一次計(jì)算的結(jié)果,而不會(huì)重新計(jì)算,顯著提高了性能
// getters
getters: {
// typescript自動(dòng)推導(dǎo)返回值類型
countMUL10(state) {
console.log("getter被調(diào)用了");
return state.count * 10;
},
// or手動(dòng)指定返回值類型
countMUL10():number {
console.log("getter被調(diào)用了");
return this.count * 10;
},
},
//component
<template>
<div>
<div>{{ store.count }}</div>
// 調(diào)用多次
<div>{{ store.countMUL10 }}</div>
<div>{{ store.countMUL10 }}</div>
<div>{{ store.countMUL10 }}</div>
<button @click="countAdd">count++</button>
</div>
</template>
store容器調(diào)用另一個(gè)store容器
如果你想在一個(gè)Store中使用另一個(gè)Store,就和在組件中使用store一樣操作就可以了
import { defineStore } from "pinia";
//導(dǎo)入一個(gè)store容器
import { useTestStore } from ".";
export const useLoginStore = defineStore("login", {
state: () => {
return {};
},
getters: {},
actions: {
handlerOtherStore() {
//得到store實(shí)例,調(diào)用實(shí)例里的方法
const testStore = useTestStore();
testStore.handleChangeState(10);
},
},
});以上就是Vue使用Pinia輕松實(shí)現(xiàn)狀態(tài)管理的詳細(xì)內(nèi)容,更多關(guān)于Vue Pinia的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
關(guān)于vue-admin-template模板連接后端改造登錄功能
這篇文章主要介紹了關(guān)于vue-admin-template模板連接后端改造登錄功能,登陸方法根據(jù)賬號(hào)密碼查出用戶信息,根據(jù)用戶id與name生成token并返回,userinfo則是對(duì)token進(jìn)行獲取,在查出對(duì)應(yīng)值進(jìn)行返回,感興趣的朋友一起看看吧2022-05-05
vue移動(dòng)端項(xiàng)目vant組件庫(kù)之tag詳解
這篇文章主要介紹了vue移動(dòng)端項(xiàng)目vant組件庫(kù)之tag詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04
詳解Vue基于vue-quill-editor富文本編輯器使用心得
這篇文章主要介紹了Vue基于vue-quill-editor富文本編輯器使用心得,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01
vue-cli項(xiàng)目?jī)?yōu)化方法- 縮短首屏加載時(shí)間
這篇文章主要介紹了vue-cli項(xiàng)目?jī)?yōu)化 縮短首屏加載時(shí)間,需要的朋友可以參考下2018-04-04
Vue項(xiàng)目打包部署到apache服務(wù)器的方法步驟
這篇文章主要介紹了Vue項(xiàng)目打包部署到apache服務(wù)器,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02
如何解決el-checkbox選中狀態(tài)更改問(wèn)題
這篇文章主要介紹了如何解決el-checkbox選中狀態(tài)更改問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
vue-pdf打包后無(wú)法預(yù)覽問(wèn)題及修復(fù)方式
這篇文章主要介紹了vue-pdf打包后無(wú)法預(yù)覽問(wèn)題及修復(fù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
詳解Vue SPA項(xiàng)目?jī)?yōu)化小記
這篇文章主要介紹了詳解Vue SPA項(xiàng)目?jī)?yōu)化小記,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
vue 項(xiàng)目中使用websocket的正確姿勢(shì)
這篇文章主要介紹了vue 項(xiàng)目中使用websocket的實(shí)例代碼,通過(guò)實(shí)例代碼給大家介紹了在utils下新建websocket.js文件的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01

