Vue新一代狀態(tài)管理工具Pinia的具體使用
前言
Pinia是尤雨溪強(qiáng)烈推薦的一款Vue狀態(tài)管理工具,也被認(rèn)為是下一代Vuex的替代產(chǎn)品。
優(yōu)點(diǎn)
- 去除了mutations,只有 state,getters和actions,其中actions支持了同步和異步操作
- 不會像Vuex那樣有模塊嵌套,Pinia只有store的概念,store之間可以相互使用,互不影響,達(dá)到模塊扁平化的效果
- 更好地支持ts
- 更好地支持Vue2/Vue3
- 邏輯更加清晰,開發(fā)起來更加簡單
安裝
npm i pinia
創(chuàng)建并掛載
1.在src目錄下新建store目錄并在其下面創(chuàng)建index.js文件,代碼如下:
import { createPinia } from 'pinia'
const store = createPinia()
export default store2.在main.js中引入store并掛載,代碼如下:
import { createApp } from 'vue'
import App from './App.vue'
import store from './store/index'
createApp(App)
.use(store)
.mount('#app')創(chuàng)建store
在src/store文件夾下創(chuàng)建一個(gè)js文件,命名按照需求即可,我這邊定義為main.js,代碼如下:
import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'hello',
count: 1
}
},
actions: {},
getters: {}
})其中defineStore的第一個(gè)參數(shù)為該store的名稱,第二個(gè)參數(shù)為一個(gè)對象,包含了該store的state,getters和actions,state改為了函數(shù)形式,目的應(yīng)該是像Vue2 options API中的data類似,避免多個(gè)store中定義的屬性相互受到影響。
使用store
此處使用Vue3的SFC語法,主要是Pinia更適合Vue3這種組合式API風(fēng)格,方便演示
回顯與修改state
<script lang="ts" setup>
import { mainStore } from '../store/main'
import { storeToRefs } from 'pinia'
const store = mainStore()
const { count } = storeToRefs(store)
// 單條數(shù)據(jù)直接修改
const handleAddCount = () => {
store.count++
}
</script>
<template>
<div>
<p>{{ store.msg }}</p>
<p>{{ count }}</p>
<button @click="handleAddCount">+</button>
</div>
</template>- 使用方法與Vuex基本類似,要使用哪個(gè)store,就直接進(jìn)行引入,非常方便,沒那么多層級引用
- 其中,我們使用了Pinia中的storeToRefs方法,此方法能夠直接解構(gòu)出該store的state中的某個(gè)值,并且是響應(yīng)式的;如果我們直接從state上解構(gòu),那么解構(gòu)出的值就不是響應(yīng)式的了。
- 如果我們要修改state中的值,不能直接去修改解構(gòu)出的值,得去修改state上對應(yīng)的屬性
使用$patch對多條數(shù)據(jù)直接修改
使用$patch的方式對數(shù)據(jù)進(jìn)行修改,可以加快修改速度,性能更好。$patch 方法可以接受兩種類型的參數(shù),對象型和回調(diào)函數(shù)型。
$patch + 對象
$patch + 函數(shù) 注:使用回調(diào)函數(shù)型時(shí),回調(diào)接收一個(gè)state參數(shù),state指代的就是對應(yīng)store中的state
使用方式如下:
<script lang="ts" setup>
import { mainStore } from '../store/main'
import { storeToRefs } from 'pinia'
const store = mainStore()
const { count } = storeToRefs(store)
// 使用$patch + 對象
const updateWithObj = () => {
store.$patch({
msg: store.msg === 'hello' ? 'hello world' : 'hello',
count: store.count + 2
})
}
// 使用$patch + 回調(diào)
const updateWithFun = () => {
store.$patch((state) => {
state.msg = state.msg === 'hello' ? 'hello world' : 'hello'
state.count = state.count + 3
})
}
</script>
<template>
<div>
<p>{{ store.msg }}</p>
<p>{{ count }}</p>
<button @click="updateWithObj">$patch+對象</button>
<button @click="updateWithFun">$patch+回調(diào)</button>
</div>
</template>使用actions
1.在src/store/main.js的actions對象中,添加一個(gè)方法,代碼如下:
import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'hello',
count: 1
}
},
actions: {
changeState() {
this.count++
this.msg = this.msg === 'hello' ? 'hello world' : 'hello'
}
},
getters: {}
})2.使用方式為:store.方法名,代碼如下:
<script lang="ts" setup>
import { mainStore } from '../store/main'
import { storeToRefs } from 'pinia'
const store = mainStore()
const { count } = storeToRefs(store)
// 使用action修改數(shù)據(jù)
const onActionClick = () => {
store.changeState()
}
</script>
<template>
<div>
<p>{{ store.msg }}</p>
<p>{{ count }}</p>
<button @click="onActionClick">使用action</button>
</div>
</template>使用getters
Pinia中的getter和Vue中的計(jì)算屬性類似,在獲取state之前會進(jìn)行處理,具有緩存性,如果值沒有改變,即使多次調(diào)用,實(shí)際上也只會調(diào)用一次。
1.在src/store/main.js的getters對象中進(jìn)行添加,代碼如下:
import { defineStore } from 'pinia'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'hello',
count: 1
}
},
getters: {
getState(state) {
console.log('getState被調(diào)用了');
// getter 中不僅可以傳遞state直接改變數(shù)據(jù),也可以使用this來改變數(shù)據(jù)
return `${state.msg} + ${this.count}`
}
}
})2.使用方式如下:
<script lang="ts" setup>
import { mainStore } from '../store/main'
const store = mainStore()
</script>
<template>
<div>
<p>使用getter獲取數(shù)據(jù):{{ store.getState }}</p>
<p>使用getter獲取數(shù)據(jù):{{ store.getState }}</p>
<p>使用getter獲取數(shù)據(jù):{{ store.getState }}</p>
</div>
</template>我們可以看到,即使執(zhí)行了三遍一樣的代碼,但最終還是只調(diào)用了一次。

多個(gè)store相互調(diào)用
在Pinia中,可以在一個(gè)store中import引入另外一個(gè)store,然后通過調(diào)用引入的store方法的形式,獲取引入的store的狀態(tài)。
1.在src/store目錄下,新建一個(gè)文件.js,代碼如下:
import { defineStore } from 'pinia'
export const userStore = defineStore('user', {
state: () => {
return {
name: '吳同學(xué)'
}
}
})2.在需要用到的store中進(jìn)行引入,并通過getters的方式獲取,代碼如下:
import { defineStore } from 'pinia'
import { userStore } from './user'
export const mainStore = defineStore('main', {
getters: {
getUserState() {
return userStore().name
}
}
})數(shù)據(jù)持久化
Pinia與Vuex一樣,刷新頁面后,數(shù)據(jù)就會重置,有時(shí)候我們需要將數(shù)據(jù)進(jìn)行持久化存儲,我們可以使用pinia-plugin-persist這個(gè)插件
安裝
npm i pinia-plugin-persist --save
使用
1.在src/store/index.js文件夾下,引入并使用,代碼如下:
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
export default store2.在對應(yīng)的store里開啟持久化存儲
import { defineStore } from 'pinia'
import { userStore } from './user'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'hello',
count: 1
}
},
// 開啟數(shù)據(jù)緩存
persist: {
enabled: true
}
})更新數(shù)據(jù)以后,我們就能在瀏覽器控制臺中看到已經(jīng)將數(shù)據(jù)存儲到了sessionStorage中

數(shù)據(jù)默認(rèn)是存在sessionStorage中的,還會以store的名稱作為key。但是我們可以對其修改,并且還可以只持久化部分state中的屬性,代碼如下:
import { defineStore } from 'pinia'
import { userStore } from './user'
export const mainStore = defineStore('main', {
state: () => {
return {
msg: 'hello',
count: 1
}
},
// 開啟數(shù)據(jù)緩存
persist: {
enabled: true,
strategies: [
{
key: 'mainStore', // 修改存在緩存中的key值
storage: localStorage, // 修改存儲方式為localStorage
paths:['msg'] // 只持久化msg,此時(shí)刷新頁面msg數(shù)據(jù)會被保留,其他state將會重置
}
]
}
})
總結(jié)
Pinia就是Vuex的替代產(chǎn)品,相比于Vuex,Pinia更好地兼容了Vue本身,代碼更加簡潔,開發(fā)起來也更加便捷。以上就是關(guān)于Pinia的介紹,如果覺得對你有幫助,就請點(diǎn)個(gè)贊,謝謝大家!
到此這篇關(guān)于Vue新一代狀態(tài)管理工具Pinia的具體使用的文章就介紹到這了,更多相關(guān)Vue狀態(tài)管理工具Pinia內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
對vue2.0中.vue文件頁面跳轉(zhuǎn)之.$router.push的用法詳解
今天小編就為大家分享一篇對vue2.0中.vue文件頁面跳轉(zhuǎn)之.$router.push的用法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08

