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 MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...