以下是一些 Pinia 的其他高階功能:
-
storeToRefs()
:響應(yīng)式解構(gòu)倉庫,保證解構(gòu)出來的數(shù)據(jù)是響應(yīng)式的數(shù)據(jù)。 -
狀態(tài)持久化:Pinia 并沒有內(nèi)置的狀態(tài)持久化功能,但你可以使用第三方庫或自定義插件來實(shí)現(xiàn)狀態(tài)的持久化。例如,你可以使用?
localStorage
?或?sessionStorage
?來將狀態(tài)保存在客戶端。 - 插件系統(tǒng):Pinia 允許你編寫自定義插件,以擴(kuò)展和定制狀態(tài)管理功能。你可以創(chuàng)建插件來處理持久化、日志記錄、錯(cuò)誤處理等任務(wù),以適應(yīng)你的特定需求。
響應(yīng)式解構(gòu)storeToRefs()
背景
在組件中訪問倉庫state
,getters
,actions
時(shí),總要在變量名前面帶上倉庫實(shí)例名,像下面這樣,每個(gè)變量都這么寫就會(huì)顯得很代碼很累贅。而直接解構(gòu)的話,數(shù)據(jù)會(huì)丟失響應(yīng)式。
import store from '@/store/senior.ts';
const userStore = store();
// 訪問state中的money,需要敲上'userStore.'
console.log(userStore.money);
// 直接解構(gòu),會(huì)丟失響應(yīng)式
const { age } = userStore;
使用
在組件中使用storeToRefs
可以保證解構(gòu)出來的數(shù)據(jù)是響應(yīng)式的數(shù)據(jù)。
import { storeToRefs } from 'pinia';
// ......
const { age } = storeToRefs(userStore);
console.log(age.value); // 別忘了 .value 這個(gè)小尾巴~
狀態(tài)持久化插件pinia-plugin-persist
pinia本身不提供持久化存儲(chǔ)狀態(tài),這里我們使用插件pinia-plugin-persist
進(jìn)行持久化存儲(chǔ)。
npm: pinia-plugin-persist
Pinia Plugin Persist
1-安裝
- yarn
yarn add pinia-plugin-persist
- npm
npm install pinia-plugin-persist
- pnpm
pnpm add pinia-plugin-persist
2-配置
在src/store/index.ts
中進(jìn)行pinia的配置
import { createPinia } from 'pinia';
// 1-引入包
import piniaPersist from 'pinia-plugin-persist';
const pinia = createPinia();
// 2-使用pinia-plugin-persist插件
pinia.use(piniaPersist);
export default pinia;
src/main.ts
// ......
import { createApp } from 'vue';
import App from './App.vue';
// 1-引入pinia配置文件
import pinia from '@/store/index.ts';
const app = createApp(App);
// 2-使用pinia配置文件
app.use(pinia);
app.mount('#app');
打開項(xiàng)目下的ts配置文件tsconfig.json
{
"compilerOptions": {
"types": [
"pinia-plugin-persist"
]
},
}
3-使用
組合式API寫法
在倉庫中的defineStore()
第三個(gè)參數(shù)進(jìn)行配置。
src/store/senior.ts
export const store = defineStore(
'senior',
() => {
const age = ref(18);
const money = ref(100);
return {
age,
money
}
},
{
persist: {
enabled: true, // 啟用持久化存儲(chǔ)
// 存儲(chǔ)策略,可以配置多個(gè)存儲(chǔ)策略,一條策略對應(yīng)一個(gè)存儲(chǔ)
strategies: [
{
key: 'local_age', // 存儲(chǔ)的key名
storage: localStorage, // 存儲(chǔ)方式
paths: ['money'] // 指定state字段進(jìn)行存儲(chǔ)
},
{
key: 'session_age',
storage: sessionStorage
}
]
}
}
);
persist
參數(shù)說明:
-
enabled
:(true
) 開啟持久化存儲(chǔ)。 -
strategies
:(Array
) 配置存儲(chǔ)策略,一條策略對應(yīng)一個(gè)存儲(chǔ)。-
key
:(String
) 存儲(chǔ)的key名。 -
storage
:(Storage
) 存儲(chǔ)方式,默認(rèn)值是sessionStorage
,可以是localStorage
,也可以自定義存儲(chǔ)方式。 -
paths
:(Array<string>
) 指定某些state字段進(jìn)行存儲(chǔ)。若不配置,默認(rèn)對整個(gè)state進(jìn)行存儲(chǔ)。
-
選項(xiàng)式API寫法
src/store/senior.ts
export const store = defineStore('senior', {
state() {
return {
age: 18,
money: 100,
}
},
persist: {
enabled: true,
strategies: [
{
key: 'local_age',
storage: localStorage,
paths: ['money']
},
{
key: 'session_age',
storage: sessionStorage
}
]
}
})
4-自定義存儲(chǔ)方式(cookie)
以下示例是對官方示例,進(jìn)行優(yōu)化的版本。
(1)安裝js-cookie
- yarn
yarn add js-cookie
- npm
npm install js-cookie
- pnpm
pnpm add js-cookie
(2)定義倉庫
src/store/senior.ts
import { defineStore } from "pinia";
import { ref } from 'vue';
import Cookies from 'js-cookie';
// 1-定義存儲(chǔ)方式cookiesStorage
const cookiesStorage: Storage = {
setItem(key, state) {
// 判斷是值,還是整個(gè)倉庫
const isKey = Object.keys(JSON.parse(state)).includes(key);
if (isKey) {
// 值
return Cookies.set(key, JSON.stringify(JSON.parse(state)[key]), { expires: 3 });
}
else {
// 倉庫state
return Cookies.set(key, state, { expires: 3 });
}
},
getItem(key) {
// 判斷鍵值是否存在
let value = Cookies.get(key);
// 這里應(yīng)該需要判斷是整個(gè)倉庫state、還是值
// 但目前沒有發(fā)現(xiàn)較好的判斷方法,所以persist必須配置paths
/*
// 如果是整個(gè)倉庫state
return value;
*/
return value ?
// 存在,返回對應(yīng)的值(parse處理,保證和原類型一致)
JSON.stringify({ [key]: JSON.parse(value) })
:
// 不存在,不做parse處理,防undefined報(bào)錯(cuò)
JSON.stringify({ [key]: value });
}
}
export const store = defineStore('senior', () => {
const age = ref(123456);
return {
age,
}
}, {
persist: {
enabled: true,
strategies: [
{
storage: cookiesStorage, // 2-使用cookiesStorage存儲(chǔ)方式
key: 'age',
paths: ['age'] // 3-必須配置paths指定state字段,否則數(shù)據(jù)會(huì)錯(cuò)亂
},
]
}
});
?。?!注意:目前,根據(jù)官方文檔的示例以及筆者的實(shí)踐,使用cookie進(jìn)行持久化存儲(chǔ),
persist.strategies
必須要配置paths
屬性,即無法默認(rèn)存儲(chǔ)整個(gè)state,否則數(shù)據(jù)會(huì)出現(xiàn)錯(cuò)亂(文章中就不演示了,有興趣的小伙伴兒可自行嘗試)。
插件系統(tǒng)
介紹
Pinia 插件是一個(gè)函數(shù),函數(shù)接收一個(gè)參數(shù)context
(上下文對象),可以獲取pinia
實(shí)例、app
應(yīng)用等。
export functionmyPiniaPlugin(context) {
context.pinia // 使用 `createPinia()` 創(chuàng)建的 pinia
context.app // 使用 `createApp()` 創(chuàng)建的當(dāng)前應(yīng)用程序(僅限 Vue 3)
context.store // 插件正在擴(kuò)充的 store
context.options // 定義存儲(chǔ)的選項(xiàng)對象傳遞給`defineStore()`
// ...
};
然后使用?pinia.use()
?將此函數(shù)傳遞給?pinia
:
pinia.use(myPiniaPlugin);
插件僅適用于在 將pinia傳遞給應(yīng)用程序后創(chuàng)建的 store,否則將不會(huì)被應(yīng)用。
功能
pinia官網(wǎng)描述pinia插件的功能:
- 向 Store 添加新屬性
- 定義 Store 時(shí)添加新選項(xiàng)
- 為 Store 添加新方法
- 包裝現(xiàn)有方法
- 更改甚至取消操作
- 實(shí)現(xiàn)本地存儲(chǔ)等副作用
- 僅適用于特定 Store
- ……
向 Store 添加新屬性
自定義插件函數(shù)返回(return
)一個(gè)對象,對象中就是需要增加的屬性。
在src/store/index.ts
中,配置pinia插件。
import { createPinia } from 'pinia';
import { ref } from 'vue';
const pinia = createPinia();
// 1-定義插件:向store增加屬性
const expandStore = () => {
// 2-這里把需要增加的屬性return出去即可
return {
hello: ref(123) // 在所有store上添加'hello'狀態(tài)
};
}
// 3-使用插件
pinia.use(expandStore);
export default pinia;
讀取 Store 配置項(xiàng)
可以通過插件函數(shù)context.options
來獲取每個(gè)store的額外配置,以便根據(jù)每個(gè)倉庫的功能進(jìn)行區(qū)別開發(fā)。
1-定義 Store 時(shí)添加新選項(xiàng)
- 在組合式API中,
defineStore()
的第三個(gè)參數(shù)就是倉庫的配置項(xiàng)。 - 在選項(xiàng)式API中,直接在
defineStore()
的第二個(gè)參數(shù)(一個(gè)對象)中添加屬性作為配置項(xiàng)。
src/store/senior.ts
組合式API
import { defineStore } from "pinia";
export const store = defineStore('senior',
() => {
return {}
},
{
haha: {
option1: '123'
}
}
);
選項(xiàng)式API
import { defineStore } from "pinia";
export const store = defineStore('senior',
{
state: () => ({}),
getters: {},
actions: {},
haha: {
option1: '123'
}
}
);
2-插件中獲取每個(gè)store的選項(xiàng)
src/store/index.ts
// 這里使用解構(gòu)賦值,把options從context中解構(gòu)出來
const expandStore = ({ options }) => {
console.log('options', options);
}
pinia.use(expandStore);
監(jiān)聽倉庫變化$subscribe()和$onAction()
在插件中使用?store.$subscribe()
和?store.$onAction()
,可以監(jiān)聽倉庫的變化。
pinia.use(({ store }) => {
store.$subscribe(() => {
// 在存儲(chǔ)變化的時(shí)候執(zhí)行
})
store.$onAction(() => {
// 在 action 的時(shí)候執(zhí)行
})
})
包裝或重寫現(xiàn)有方法
重寫$reset方法
可以參考上一篇博文,重寫了$reset方法:vue3探索——5分鐘快速上手大菠蘿pinia文章來源:http://www.zghlxwxcb.cn/news/detail-709819.html
import { createPinia } from 'pinia';
const pinia = createPinia();
// 1-使用pinia自定義插件
pinia.use(({ store }) => {
// 2-獲取最開始的State
const initialState = JSON.parse(JSON.stringify(store.$state));
// 3-重寫$reset()方法
store.$reset = () => {
// 4-利用$patch()批量變更state,達(dá)到重置state的目的
store.$patch(initialState);
}
});
export default pinia;
暫時(shí)沒有更多辣~文章來源地址http://www.zghlxwxcb.cn/news/detail-709819.html
到了這里,關(guān)于vue3探索——pinia高階使用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!