vue3探索——pinia高階使用

来源:https://www.cnblogs.com/cry0-0/archive/2023/09/16/17707386.html
-Advertisement-
Play Games

以下是一些 Pinia 的其他高階功能: storeToRefs():響應式解構倉庫,保證解構出來的數據是響應式的數據。 狀態持久化:Pinia 並沒有內置的狀態持久化功能,但你可以使用第三方庫或自定義插件來實現狀態的持久化。例如,你可以使用 localStorage 或 sessionStorag ...


以下是一些 Pinia 的其他高階功能:

  1. storeToRefs():響應式解構倉庫,保證解構出來的數據是響應式的數據。
  2. 狀態持久化:Pinia 並沒有內置的狀態持久化功能,但你可以使用第三方庫或自定義插件來實現狀態的持久化。例如,你可以使用 localStorage 或 sessionStorage 來將狀態保存在客戶端。
  3. 插件系統:Pinia 允許你編寫自定義插件,以擴展和定製狀態管理功能。你可以創建插件來處理持久化、日誌記錄、錯誤處理等任務,以適應你的特定需求。

響應式解構storeToRefs()

背景

在組件中訪問倉庫state,getters,actions時,總要在變數名前面帶上倉庫實例名,像下麵這樣,每個變數都這麼寫就會顯得很代碼很累贅。而直接解構的話,數據會丟失響應式。

import store from '@/store/senior.ts';
const userStore = store();
// 訪問state中的money,需要敲上'userStore.'
console.log(userStore.money);

// 直接解構,會丟失響應式
const { age } = userStore;

使用

在組件中使用storeToRefs可以保證解構出來的數據是響應式的數據。

import { storeToRefs } from 'pinia';
// ......
const { age } = storeToRefs(userStore);
console.log(age.value); // 別忘了 .value 這個小尾巴~

狀態持久化插件pinia-plugin-persist

pinia本身不提供持久化存儲狀態,這裡我們使用插件pinia-plugin-persist 進行持久化存儲。

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中進行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');

打開項目下的ts配置文件tsconfig.json

{
  "compilerOptions": {
    "types": [
      "pinia-plugin-persist"
    ]
  },
}

3-使用

組合式API寫法

在倉庫中的defineStore() 第三個參數進行配置。

src/store/senior.ts

export const store = defineStore(
    'senior',
    () => {
        const age = ref(18);
        const money = ref(100);

        return {
            age,
            money
        }
    },
    {
        persist: {
            enabled: true, // 啟用持久化存儲
            // 存儲策略,可以配置多個存儲策略,一條策略對應一個存儲
            strategies: [
                {
                    key: 'local_age', // 存儲的key名
                    storage: localStorage, // 存儲方式
                    paths: ['money'] // 指定state欄位進行存儲
                },
                {
                    key: 'session_age',
                    storage: sessionStorage
                }
            ]
        }
    }
);

persist參數說明:

  • enabled:(true) 開啟持久化存儲。
  • strategies:(Array) 配置存儲策略,一條策略對應一個存儲。
    • key:(String) 存儲的key名。
    • storage:(Storage) 存儲方式,預設值是sessionStorage,可以是localStorage,也可以自定義存儲方式。
    • paths:(Array<string>) 指定某些state欄位進行存儲。若不配置,預設對整個state進行存儲。

選項式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-自定義存儲方式(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-定義存儲方式cookiesStorage
const cookiesStorage: Storage = {
    setItem(key, state) {
        // 判斷是值,還是整個倉庫
        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);

        // 這裡應該需要判斷是整個倉庫state、還是值
        // 但目前沒有發現較好的判斷方法,所以persist必須配置paths
        /*
            // 如果是整個倉庫state
            return value;
        */

        return value ?
            // 存在,返回對應的值(parse處理,保證和原類型一致)
            JSON.stringify({ [key]: JSON.parse(value) })
            :
            // 不存在,不做parse處理,防undefined報錯
            JSON.stringify({ [key]: value });
    }
}

export const store = defineStore('senior', () => {
    const age = ref(123456);

    return {
        age,
    }
}, {
    persist: {
        enabled: true,
        strategies: [
            {
                storage: cookiesStorage, // 2-使用cookiesStorage存儲方式
                key: 'age',
                paths: ['age'] // 3-必須配置paths指定state欄位,否則數據會錯亂
            },
        ]
    }
});

!!!註意:目前,根據官方文檔的示例以及筆者的實踐,使用cookie進行持久化存儲,persist.strategies必須要配置paths 屬性,即無法預設存儲整個state,否則數據會出現錯亂(文章中就不演示了,有興趣的小伙伴兒可自行嘗試)。

插件系統

介紹

Pinia 插件是一個函數,函數接收一個參數context(上下文對象),可以獲取pinia實例、app應用等。

export functionmyPiniaPlugin(context) {
  context.pinia // 使用 `createPinia()` 創建的 pinia
  context.app // 使用 `createApp()` 創建的當前應用程式(僅限 Vue 3)
  context.store // 插件正在擴充的 store
  context.options // 定義存儲的選項對象傳遞給`defineStore()`
	// ...
};

然後使用 pinia.use() 將此函數傳遞給 pinia

pinia.use(myPiniaPlugin);

插件僅適用於在 將pinia傳遞給應用程式後創建的 store,否則將不會被應用。

功能

pinia官網描述pinia插件的功能:

  • 向 Store 添加新屬性
  • 定義 Store 時添加新選項
  • 為 Store 添加新方法
  • 包裝現有方法
  • 更改甚至取消操作
  • 實現本地存儲等副作用
  • 適用於特定 Store
  • ……

向 Store 添加新屬性

自定義插件函數返回(return)一個對象,對象中就是需要增加的屬性。

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'狀態
    };
}
// 3-使用插件
pinia.use(expandStore);

export default pinia;

讀取 Store 配置項

可以通過插件函數context.options 來獲取每個store的額外配置,以便根據每個倉庫的功能進行區別開發。

1-定義 Store 時添加新選項

  • 在組合式API中,defineStore() 的第三個參數就是倉庫的配置項。
  • 在選項式API中,直接在defineStore() 的第二個參數(一個對象)中添加屬性作為配置項。

src/store/senior.ts

組合式API

import { defineStore } from "pinia";
export const store = defineStore('senior',
    () => {
        return {}
    },
    {
        haha: {
            option1: '123'
        }
    }
);

選項式API

import { defineStore } from "pinia";
export const store = defineStore('senior',
    {
        state: () => ({}),
        getters: {},
        actions: {},
        haha: {
            option1: '123'
        }
    }
);

2-插件中獲取每個store的選項

src/store/index.ts

// 這裡使用解構賦值,把options從context中解構出來
const expandStore = ({ options }) => {
    console.log('options', options);
}
pinia.use(expandStore);

監聽倉庫變化$subscribe()$onAction()

在插件中使用 store.$subscribe()和 store.$onAction(),可以監聽倉庫的變化。

pinia.use(({ store }) => {
  store.$subscribe(() => {
    // 在存儲變化的時候執行
  })
  store.$onAction(() => {
    // 在 action 的時候執行
  })
})

包裝或重寫現有方法

重寫$reset方法

可以參考上一篇博文,重寫了$reset方法:vue3探索——5分鐘快速上手大菠蘿pinia

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,達到重置state的目的
        store.$patch(initialState);
    }
});
 
export default pinia;

暫時沒有更多辣~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 插件式架構,一種全新的、開放性的、高擴展性的架構體系。插件式架構設計好處很多,把擴展功能從框架中剝離出來,降低了框架的複雜度,讓框架更容易實現。擴展功能與框架以一種很松的方式耦合,兩者在保持介面不變的情況下,可以獨立變化和發佈。基於插件設計並不神秘,相反它比起一團泥的設計更簡單,更容易理解。 ...
  • 以下內容均來自Gitee的開源倉庫,具體的使用請移步Gitee:https://gitee.com/pojianbing/lazy-captcha 以下是我自己使用的具體方式 首先安裝NuGet包: Microsoft.Extensions.Caching.StackExchangeRedis La ...
  • 本文討論了零拷貝在優化數據傳輸效率方面的局限性。儘管零拷貝技術在減少數據傳輸過程中的記憶體拷貝次數方面有很大的優勢,但它並非適用於所有情況。文章介紹了一些其他的優化方法,如非同步I/O和直接I/O的組合、根據文件大小選擇不同的優化方式。至此,我們的電腦基礎專欄就結束了,不知道大家有沒有發現,操作系統底... ...
  • 1.列定義 說明:在MySQL中,列定義(Column Definition)是用於定義資料庫表中每一列的結構的語句。它指定了列的名稱、數據類型、長度、約束以及其他屬性。 2.主鍵和自增 主鍵:PRIMARY KEY是資料庫表中的一個欄位,被用作主鍵。主鍵用於唯一標識表中的每一行/記錄。在創建表時, ...
  • 在MySQL資料庫中,增刪改查操作是指對數據進行添加、刪除、查詢和修改的操作。這些操作在資料庫管理和維護中非常重要,可以幫助資料庫管理員和開發人員有效地管理數據和實現各種複雜的數據處理需求。 添加數據(增加操作):在MySQL中,添加數據通常使用INSERT語句。通過INSERT語句,開發人員可以將 ...
  • 數據類型的介紹: 數據類型(data_type)是指系統中所允許的數據的類型。資料庫中的每個列都應有適當的數據類型,用於限制或允許該列中存儲的數據。例如,列中存儲的為數字,則相應的數據類型應該為數值類型。 如果使用錯誤的數據類型可能會嚴重影響應用程式的功能和性能,所以在設計表時,應該特別重視數據列所 ...
  • 上文說到,資料庫的安裝和連接,接下來將給大家講解MySQL資料庫的基本語法及數據的類型 1.基本語法 (1).查看當前所有資料庫 : show databases; (2).創建資料庫 create database 資料庫名; 例如: create database gzy; (3).如果不確定數 ...
  • 1.MySQL是什麼? MySQL是一個關係型資料庫管理系統,由瑞典MySQL AB 公司開發,屬於 Oracle 旗下產品。它是最流行的關係型資料庫管理系統之一,在 WEB 應用方面,MySQL是最好的 RDBMS (Relational Database Management System,關係 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 微服務架構已經成為搭建高效、可擴展系統的關鍵技術之一,然而,現有許多微服務框架往往過於複雜,使得我們普通開發者難以快速上手並體驗到微服務帶了的便利。為瞭解決這一問題,於是作者精心打造了一款最接地氣的 .NET 微服務框架,幫助我們輕鬆構建和管理微服務應用。 本框架不僅支持 Consul 服務註 ...
  • 先看一下效果吧: 如果不會寫動畫或者懶得寫動畫,就直接交給Blend來做吧; 其實Blend操作起來很簡單,有點類似於在操作PS,我們只需要設置關鍵幀,滑鼠點來點去就可以了,Blend會自動幫我們生成我們想要的動畫效果. 第一步:要創建一個空的WPF項目 第二步:右鍵我們的項目,在最下方有一個,在B ...
  • Prism:框架介紹與安裝 什麼是Prism? Prism是一個用於在 WPF、Xamarin Form、Uno 平臺和 WinUI 中構建鬆散耦合、可維護和可測試的 XAML 應用程式框架 Github https://github.com/PrismLibrary/Prism NuGet htt ...
  • 在WPF中,屏幕上的所有內容,都是通過畫筆(Brush)畫上去的。如按鈕的背景色,邊框,文本框的前景和形狀填充。藉助畫筆,可以繪製頁面上的所有UI對象。不同畫筆具有不同類型的輸出( 如:某些畫筆使用純色繪製區域,其他畫筆使用漸變、圖案、圖像或繪圖)。 ...
  • 前言 嗨,大家好!推薦一個基於 .NET 8 的高併發微服務電商系統,涵蓋了商品、訂單、會員、服務、財務等50多種實用功能。 項目不僅使用了 .NET 8 的最新特性,還集成了AutoFac、DotLiquid、HangFire、Nlog、Jwt、LayUIAdmin、SqlSugar、MySQL、 ...
  • 本文主要介紹攝像頭(相機)如何採集數據,用於類似攝像頭本地顯示軟體,以及流媒體數據傳輸場景如傳屏、視訊會議等。 攝像頭採集有多種方案,如AForge.NET、WPFMediaKit、OpenCvSharp、EmguCv、DirectShow.NET、MediaCaptre(UWP),網上一些文章以及 ...
  • 前言 Seal-Report 是一款.NET 開源報表工具,擁有 1.4K Star。它提供了一個完整的框架,使用 C# 編寫,最新的版本採用的是 .NET 8.0 。 它能夠高效地從各種資料庫或 NoSQL 數據源生成日常報表,並支持執行複雜的報表任務。 其簡單易用的安裝過程和直觀的設計界面,我們 ...
  • 背景需求: 系統需要對接到XXX官方的API,但因此官方對接以及管理都十分嚴格。而本人部門的系統中包含諸多子系統,系統間為了穩定,程式間多數固定Token+特殊驗證進行調用,且後期還要提供給其他兄弟部門系統共同調用。 原則上:每套系統都必須單獨接入到官方,但官方的接入複雜,還要官方指定機構認證的證書 ...
  • 本文介紹下電腦設備關機的情況下如何通過網路喚醒設備,之前電源S狀態 電腦Power電源狀態- 唐宋元明清2188 - 博客園 (cnblogs.com) 有介紹過遠程喚醒設備,後面這倆天瞭解多了點所以單獨加個隨筆 設備關機的情況下,使用網路喚醒的前提條件: 1. 被喚醒設備需要支持這WakeOnL ...
  • 前言 大家好,推薦一個.NET 8.0 為核心,結合前端 Vue 框架,實現了前後端完全分離的設計理念。它不僅提供了強大的基礎功能支持,如許可權管理、代碼生成器等,還通過採用主流技術和最佳實踐,顯著降低了開發難度,加快了項目交付速度。 如果你需要一個高效的開發解決方案,本框架能幫助大家輕鬆應對挑戰,實 ...