Vue替代vuex的存儲(chǔ)庫Pinia詳細(xì)介紹
前言
vue3已經(jīng)發(fā)布很長一段時(shí)間了,vue官網(wǎng)也已經(jīng)默認(rèn)訪問vue3的文檔了。因此打算系系統(tǒng)統(tǒng)仔仔細(xì)細(xì)的學(xué)習(xí)一波
使用官方提供的腳手架工具新建一個(gè)vue3項(xiàng)目會(huì)發(fā)現(xiàn),官方已將pinia作為默認(rèn)的狀態(tài)存儲(chǔ)庫提供在安裝選項(xiàng)中了。
vuex的倉庫中官方也有這么一段提示:
大致是說:Pinia 現(xiàn)在是新的默認(rèn)設(shè)置。Vue 的官方狀態(tài)管理庫已更改為Pinia。您可以簡單地將 Pinia 視為具有不同名稱的 Vuex 5。Pinia 也適用于 Vue 2.x。Vuex 3 和 4 仍將被維護(hù)。但是,不太可能為其添加新功能。如果您打算開始一個(gè)新項(xiàng)目,我們強(qiáng)烈建議您使用 Pinia。
本文就來介紹打敗vuex的新一代vue存儲(chǔ)庫Pinia究竟有和神奇魔法~
Pinia介紹
u1s1,logo真可愛~
Pinia(發(fā)音為 /pi?nj?/,類似于英語中的“peenya”)是最接近有效包名 piña(西班牙語中的_pineapple_)的詞。 菠蘿實(shí)際上是一組單獨(dú)的花朵,它們結(jié)合在一起形成多個(gè)水果。 與 Store 類似,每一家都是獨(dú)立誕生的,但最終都是相互聯(lián)系的。 它也是一種美味的熱帶水果,原產(chǎn)于南美洲。
1. 創(chuàng)建一個(gè)Pinia store
安裝pinia
npm install pinia
注意雖然pinia支持vue2.x和vue3.x,但是如果你的vue的版本低于2.7,還需要安裝組合API:@vue/composition-api。
2. 創(chuàng)建一個(gè)根存儲(chǔ)并傳遞給應(yīng)用程序
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) app.use(createPinia()) app.mount('#app')
如果你使用的是vue2,還需要安裝一個(gè)插件并將創(chuàng)建的pinia注入應(yīng)用程序的根目錄
import { createPinia, PiniaVuePlugin } from 'pinia' Vue.use(PiniaVuePlugin) const pinia = createPinia() new Vue({ el: '#app', // 其他選項(xiàng)... // ... // 注意同一個(gè) `pinia` 實(shí)例可以在多個(gè) Vue 應(yīng)用程序中使用 // 同一個(gè)頁面 pinia, })
3. 定義一個(gè)store
export const useCounterStore = defineStore('counter', { state: () => { return { count: 0, msg: '開心', todoList: ['吃飯', '繪畫'] } }, getters: { doubleCount(state) { return state.count * 2 } }, actions: { increment(payload?: number) { this.count = payload ? this.count + payload : this.count + 1 } } })
2. 訪問State
<template> <div class="about"> <p>{{ counterStore.msg }}</p> <p>{{ counterStore.count }}</p> <p>{{ counterStore.doubleCount }}</p> <p @click="() =>counterStore.increment(3)">點(diǎn)擊我+1</p> </div> </template> <script setup lang="ts"> import { storeToRefs } from 'pinia' import { useCounterStore } from '@/stores/counter' const counterStore = useCounterStore() </script>
你也可以使用storeToRefs進(jìn)行解構(gòu)
<template> <div class="about"> <p>{{ count }}</p> <p>{{ msg }}</p> <p>{{ doubleCount }}</p> <ul> <li v-for="(item, index) in todoList" :key="index">{{ item }}</li> </ul> </div> </template> <script setup lang="ts"> import { storeToRefs } from 'pinia' import { useCounterStore } from '@/stores/counter' const counterStore = useCounterStore() // 也可以使用storeToRefs進(jìn)行解構(gòu) let { count, doubleCount, msg, todoList } = storeToRefs(counterStore) </script>
3. Pinia修改數(shù)據(jù)的四種方法
直接修改
counterStore.count++
$patch
$patch 方法允許你使用部分“state”對(duì)象同時(shí)應(yīng)用多個(gè)更改。 但是,使用這種語法應(yīng)用某些突變非常困難或代價(jià)高昂:任何集合修改(例如,從數(shù)組中推送、刪除、拼接元素)都需要?jiǎng)?chuàng)建一個(gè)新集合。
const newTodoList = [...counterStore.todoList, '睡午覺'] counterStore.$patch({ count: 100, msg: '哈哈', todoList: newTodoList })
$patch傳遞函數(shù)
$patch 方法也接受一個(gè)函數(shù)來批量修改集合內(nèi)部分對(duì)象的情況
counterStore.$patch((state) => { state.count = 100, state.msg = '哈哈', state.todoList.push('聽音樂') })
action
當(dāng)業(yè)務(wù)邏輯很復(fù)雜的時(shí)候,可以將方法寫在store中的action里
actions: { increment(payload?: number) { this.count = payload ? this.count + payload : this.count + 1 } }
4. 重置State
可以通過調(diào)用 store 上的 $reset() 方法將狀態(tài) 重置 到其初始值
counterStore.$reset()
5. 替換state
通過將其 $state 屬性設(shè)置為新對(duì)象來替換 Store 的整個(gè)狀態(tài)
counterStore.$state = {<!--{C}%3C!%2D%2D%20%2D%2D%3E--> counter: 666, msg: 'Paimon', todoList: [] }
也可以通過更改 pinia 實(shí)例的 state 來替換應(yīng)用程序的整個(gè)狀態(tài)。 這在 SSR for hydration 期間使用。
pinia.state.value = {}
6. 訂閱狀態(tài)
可以通過 store 的 $subscribe() 方法查看狀態(tài)及其變化,類似于 Vuex 的 subscribe 方法。 與常規(guī)的 watch() 相比,使用 $subscribe() 的優(yōu)點(diǎn)是 subscriptions 只會(huì)在 patches 之后觸發(fā)一次。
counterStore.$subscribe((mutation, state) => { // 每當(dāng)它發(fā)生變化時(shí),將整個(gè)狀態(tài)持久化到本地存儲(chǔ) localStorage.setItem('cart', JSON.stringify(state)) })
7. Getters
Getter 完全等同于 Store 狀態(tài)的 計(jì)算值。 它們可以用 defineStore() 中的 getters 屬性定義。 他們接收“狀態(tài)”作為第一個(gè)參數(shù)以鼓勵(lì)箭頭函數(shù)的使用。
export const useCounterStore = defineStore('counter', { state: () => { return { count: 0, msg: '開心', todoList: ['吃飯', '繪畫'] } }, getters: { //自動(dòng)將返回類型推斷為數(shù)字 doubleCount(state) { return state.count * 2 } } })
在getters中使用其他 getter:
getters: { // 返回類型必須明確設(shè)置 doublePlusOne():number { return this.doubleCount + 1 } }
將參數(shù)傳遞給 getter:
getters: { getUserById: (state) => { return (userId) => state.users.find((user) => user.id === userId) }, }
在組件中這樣使用:
<template> <p>User 2: {{ counterStore.getUserById(2) }}</p> </template>
與vuex比較
Pinia 最初是為了探索 Vuex 的下一次迭代會(huì)是什么樣子,結(jié)合了 Vuex 5 核心團(tuán)隊(duì)討論中的許多想法。最終,團(tuán)隊(duì)意識(shí)到 Pinia 已經(jīng)實(shí)現(xiàn)了他們?cè)?Vuex 5 中想要的大部分內(nèi)容,并決定實(shí)現(xiàn)它。與 Vuex 相比,Pinia 提供了一個(gè)更簡單的 API,具有更少的規(guī)范,提供了 Composition-API 風(fēng)格的 API,最重要的是,在與 TypeScript 一起使用時(shí)具有可靠的類型推斷支持。
- mutations 不再存在。他們經(jīng)常被認(rèn)為是 非常 冗長。他們最初帶來了 devtools 集成,但這不再是問題。
- 無需創(chuàng)建自定義復(fù)雜包裝器來支持 TypeScript,所有內(nèi)容都是類型化的,并且 API 的設(shè)計(jì)方式盡可能利用 TS 類型推斷。
- 不再需要注入、導(dǎo)入函數(shù)、調(diào)用函數(shù)、享受自動(dòng)完成功能
- 無需動(dòng)態(tài)添加 Store,默認(rèn)情況下它們都是動(dòng)態(tài)的,您甚至都不會(huì)注意到。請(qǐng)注意,您仍然可以隨時(shí)手動(dòng)使用 Store 進(jìn)行注冊(cè),但因?yàn)樗亲詣?dòng)的,您無需擔(dān)心
- 不再有 modules 的嵌套結(jié)構(gòu)。您仍然可以通過在另一個(gè) Store 中導(dǎo)入和 使用 來隱式嵌套 Store,但 Pinia 通過設(shè)計(jì)提供平面結(jié)構(gòu),同時(shí)仍然支持 Store 之間的交叉組合方式。 您甚至可以擁有 Store 的循環(huán)依賴關(guān)系。
- 沒有命名空間模塊。鑒于 Store 的扁平架構(gòu),“命名空間” Store 是其定義方式所固有的,您可以說所有 Store 都是命名空間的。
Pinia的優(yōu)點(diǎn)
- 同時(shí)支持vue2與vue3
- 摒棄了mutations,只有state,getter,action
- Actions支持同步和異步
- 更符合Vue3的Composition api
- 天然支持ts
到此這篇關(guān)于Vue替代vuex的存儲(chǔ)庫Pinia詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Vue Pinia內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Vue父子組件通信實(shí)現(xiàn)todolist的功能示例代碼
這篇文章主要給大家介紹了關(guān)于如何使用Vue父子組件通信實(shí)現(xiàn)todolist的功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04go-gin-vue3-elementPlus帶參手動(dòng)上傳文件的案例代碼
這篇文章主要介紹了go-gin-vue3-elementPlus帶參手動(dòng)上傳文件的案例代碼,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11vue-cli 使用vue-bus來全局控制的實(shí)例講解
今天小編就為大家分享一篇 vue-cli使用vue-bus來全局控制的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09