Vue3中的pinia使用方法總結(建議收藏版)
1.pinia介紹
pinia 是 Vue 的存儲庫,它允許您跨組件/頁面共享狀態(tài)。就是和vuex一樣的實現(xiàn)數據共享。
依據Pinia官方文檔,Pinia是2019年由vue.js官方成員重新設計的新一代狀態(tài)管理器,更替Vuex4成為Vuex5。
Pinia 目前也已經是 vue 官方正式的狀態(tài)庫。適用于 vue2 和 vue3??梢院唵蔚睦斫獬?Pinia 就是 Vuex5。也就是說, Vue3 項目,建議使用Pinia。
Pinia 的優(yōu)點
- pinia 符合直覺,易于學習。
- pinia 是輕量級狀態(tài)管理工具,大小只有1KB.
- pinia 模塊化設計,方便拆分。
- pinia 沒有 mutations,直接在 actions 中操作 state,通過 this.xxx 訪問響應的狀態(tài),盡管可 以直接操作 state,但是還是推薦在 actions 中操作,保證狀態(tài)不被意外的改變。
- store 的 action 被調度為常規(guī)的函數調用,而不是使用 dispatch 方法或者是 MapAction 輔助函數,這是在 Vuex 中很常見的。
- 支持多個 store。
- 支持 Vue devtools、SSR、webpack 代碼拆分。
更多查看文檔…
2.pinia基本使用
1.首先先安裝依賴
npm install pinia
2.在main.js中引入pinia并創(chuàng)建容器掛載到根實例上
//引入stores暴露出的pinia的實例
import pinia from './stores'
createApp(App).use(pinia).mount('#app')
3.創(chuàng)建stores文件夾和index.js文件(這個文件以后基本不用管了)
import { createPinia } from "pinia";
const pinia = createPinia()
export default pinia
4.在stores文件夾下創(chuàng)建counter.js文件。這個文件就是存有關counter相關的數據。(類似vuex的模塊化)
defineStore 是需要傳參數的,
- 第一個參數是id,就是一個唯一的值,簡單點說就可以理解成是一個命名空間.
- 第二個參數就是一個對象,里面有三個模塊需要處理,第一個是 state,第二個是 getters,第三個是 actions。
//定義關于counter的store
import {defineStore} from 'pinia'
/*defineStore 是需要傳參數的,其中第一個參數是id,就是一個唯一的值,
簡單點說就可以理解成是一個命名空間.
第二個參數就是一個對象,里面有三個模塊需要處理,第一個是 state,
第二個是 getters,第三個是 actions。
*/
const useCounter = defineStore("counter",{
state:() => ({
count:66,
}),
getters: {
},
actions: {
}
})
//暴露這個useCounter模塊
export default useCounter
注意:返回的函數統(tǒng)一使用useXXX作為命名方案,這是約定的規(guī)矩。例如上面的useCounter
5.然后再組件中使用:
<template>
<!-- 在頁面中直接使用就可以了 不用 .state-->
<div>展示pinia的counter的count值:{{counterStore.count}}</div>
</template>
<script setup>
// 首先需要引入一下我們剛剛創(chuàng)建的store
import useCounter from '../stores/counter'
// 因為是個方法,所以我們得調用一下
const counterStore = useCounter()
</script>
注意:在模板使用 ,不用和vuex一樣還要.state,直接點state里面的K
運行效果: 可以用vue3的調試工具看pinia

2.1注意Store獲取到后不能解構,否則失去響應式
案例需求,點擊按鈕加一:
一個不解構,一個不解構看看區(qū)別。
<template>
<div>展示pinia的counter的count值:{{counterStore.count}}</div>
<div>展示解構出來的pinia的counter的count值:{{count}}</div>
<button @click="addCount">count+1</button>
</template>
<script setup>
import useCounter from '../stores/counter'
const counterStore = useCounter()
const {count} = counterStore
function addCount(){
//這里可以直接操作count,這就是pinia好處,在vuex還要commit在mutaitions修改數據
counterStore.count++
}
<script/>
在 vuex 里面是堅決不允許這樣子直接操作 state 數據的,pinia是可以的,看看上面的addCount函數直接操作。
運行結果:

解決方案:
pinia提供了一個函數storeToRefs解決。引用官方API storeToRef 作用就是把結構的數據使用ref做代理
import {storeToRefs} from 'pinia'
const counterStore = useCounter()
const {count} = storeToRefs(counterStore)現(xiàn)在數據都是響應式的了

3.修改state的數據
重新新建一個user模塊
stores/user.js
//定義一個關于user的store
import {defineStore} from 'pinia'
const useUser = defineStore("user",{
state:()=>({
name:"紫陌",
age:18
})
})
export default useUser
組件中修改數據:
**第一種方法:**點擊按鈕修改數據,這種方法是最直接的修改數據
<template>
<div>
<h2>名字是:{{name}}</h2>
<h2>年齡是:{{age}}</h2>
<button @click="updateStore">修改Store數據</button>
</div>
</template>
<script setup>
import useUser from '../stores/user'
import {storeToRefs} from 'pinia'
const userStore = useUser()
const {name,age} = storeToRefs(userStore)
function updateStore(){
//一個個的修改狀態(tài)
userStore.name = "zimo"
userStore.age = 20
}效果:點擊也修改了

第二種方法:$patch函數修改
function updateStore(){
//一個個的修改狀態(tài)
// userStore.name = "zimo"
// userStore.age = 20
// 一次性修改多個狀態(tài)
userStore.$patch({
name:"zimo",
age:20
})
}
這個方式也可以,效果一樣。
第三種方法:$state 方式(這個是替換的方式。)這個基本不用,這里就不多說。可以看查閱文檔。
第四種方法:$reset()函數是重置state數據的
新增一個重置按鈕:
function resetStore(){
userStore.$reset()
}
運行結果:點擊了修改數據按鈕之后在點重置按鈕就恢復原始的數據。

4.getters的使用
getters 類似于 vue 里面的計算屬性,可以對已有的數據進行修飾。不管調用多少次,getters中的函數只會執(zhí)行一次,且都會緩存。
1.最基本的使用
在counter模塊演示了,counter模塊:
//定義關于counter的store
import {defineStore} from 'pinia'
const useCounter = defineStore("counter",{
state:() => ({
count:66,
}),
getters:{
//基本使用
doubleCount(state) {
return state.count * 2
},
},
})
//暴露這個useCounter模塊
export default useCounter
組件中:
<div>
<h1>getters的使用</h1>
<h2>doubleCount:{{counterStore.doubleCount}}</h2>
</div>
運行效果:

這樣就是最基本的使用了。
2.一個getter引入另外一個getter
couter模塊:
getters:{
//基本使用
doubleCount(state) {
return state.count * 2
},
//一個getter引入另外一個getter
doubleCountAddTwo(){
console.log(this);
//this.是store實例
return this.doubleCount + 2
}
},
組件中使用:
<div>
<h1>getters的使用</h1>
<h2>doubleCount:{{counterStore.doubleCount}}</h2>
<h2>doubleCountAddTwo:{{counterStore.doubleCountAddTwo}}</h2>
</div>
運行效果并且看看打印的this:


3.getters中用別的store中的數據
在counter模塊中拿user模塊的store數據。
count模塊:
//定義關于counter的store
import {defineStore} from 'pinia'
import useUser from "./user"
const useCounter = defineStore("counter",{
state:() => ({
count:66,
}),
getters:{
//基本使用
doubleCount(state) {
return state.count * 2
},
//一個getter引入另外一個getter
doubleCountAddTwo(){
console.log(this);
//this.是store實例
return this.doubleCount + 2
},
//getters中用別的store中的數據
showMessage(state){
console.log(state);
console.log(this)
//獲取user信息,拿到useUser模塊
const userStore = useUser()
//拼接信息
return `name:${userStore.name}--count:${state.count}`
}
},
})
//暴露這個useCounter模塊
export default useCounter
注意:要引入user模塊
組件中:
<div>
<h1>getters的使用</h1>
<h2>doubleCount:{{counterStore.doubleCount}}</h2>
<h2>doubleCountAddTwo:{{counterStore.doubleCountAddTwo}}</h2>
<h2>showMessage:{{counterStore.showMessage}}</h2>
</div>
運行結果:

注意:我打印了this和store,他們都是當前這這個模塊的實例

這樣就在counter模塊拿到了user模塊的數據了。
5. actions的使用
actions 是可以處理同步,也可以處理異步,同步的話相對來說簡單一點.actions類似methods
1.先看同步使用:
counter模塊使用:
在actions定義了兩個函數一個加一的函數,一個加20的函數。
//定義關于counter的store
import {defineStore} from 'pinia'
const useCounter = defineStore("counter",{
state:() => ({
count:66,
}),
actions:{
increment(state){
//actions沒有state,只能通過this拿store,這里打印
console.log(state);
this.count++
},
incrementNum(num){
this.count += num
}
}
})
//暴露這個useCounter模塊
export default useCounter
組件中:
actions函數在組件中使用
<div>
<h1>actions的使用</h1>
<h2>count的事值:{{counterStore.count}}</h2>
<button @click="changeState">count+1</button>
<button @click="incrementNum">count+20</button>
</div>
<script setup>
import useCounter from '../stores/counter'
const counterStore = useCounter()
function changeState(){
counterStore.increment()
}
function incrementNum(){
counterStore.incrementNum(20)
}
</script>
運行結果并且看看state是什么
初始值是66,點了一次加1和點了一次加20

注意:state的結果是undefined 所以actions只能通過this訪問store。getter的話state和this都能訪問。

2.異步操作使用
在 actions 處理異步的時候呢,我們一般是與 async 和 await 連用。
counter模塊: 這里大致演示,具體還看自己怎么使用。
state:() => ({
count:66,
list:[]
}),
actions:{
//大概演示這個異步流程
async axiosData(){
const res = await fetch("http://-----------------")
if(code ==200){
//收到數據保存到store
this.list = res.data.list
return "ok"
}
}
}
組件使用:
<template>
<!-- 遍歷store的數據 -->
<div v-for="item in counterStore.list"></div>
</template>
<script setup>
import useCounter from '../stores/counter'
const counterStore = useCounter()
counterStore.axiosData().then(res =>{
console.log("成功",res);
})
</script>
就這樣可以啦?。。?/p>
是不是比vuex簡潔很多。。。
6.數據的持久化
pinia支持擴展插件
我們想實現(xiàn)數據持久化
npm i pinia-plugin-persist
export const useUserStore = defineStore({
state () {
return {
count: 0,
num: 101,
list: [1, 2, 3, 4 ]
}
},
persist: {
enabled: true, // 開啟緩存 默認會存儲在本地localstorage
storage: sessionStorage, // 緩存使用方式
paths:[] // 需要緩存鍵
}
})效果:

總結
到此這篇關于Vue3中pinia使用的文章就介紹到這了,更多相關Vue3中pinia使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Vue3之狀態(tài)管理器(Pinia)詳解及使用方式
- Vue3狀態(tài)管理之Pinia的入門使用教程
- vue3項目使用pinia狀態(tài)管理器的使用
- vue3項目引入pinia報錯的簡單解決
- vue3 pinia踩坑及解決方案詳解
- Vue3中pinia的使用與持久化處理詳解
- Vue3組件不發(fā)生變化如何監(jiān)聽pinia中數據變化
- vue3中vuex與pinia的踩坑筆記記錄
- vue3搭配pinia的踩坑實戰(zhàn)記錄
- vue3?pinia實現(xiàn)持久化詳解
- vue3中使用pinia(大菠蘿)狀態(tài)管理倉庫的項目實踐
- Vue3 狀態(tài)管理 Pinia 入門指南
相關文章
使用vue-route 的 beforeEach 實現(xiàn)導航守衛(wèi)(路由跳轉前驗證登錄)功能
在網站中普遍會遇到這樣的需求,路由跳轉前做一些驗證,比如登錄驗證(未登錄去登錄頁)。下面腳本之家小編給大家?guī)砹耸褂胿ue-route 的 beforeEach 實現(xiàn)導航守衛(wèi)(路由跳轉前驗證登錄)功能,感興趣的朋友一起看看吧2018-03-03

