Day13 提到 localStorage 的儲存方式,可於瀏覽器本地保存資料到使用者電腦,資料會永久保留,除非使用者主動清除。localStorage 適合保存需要跨頁或長期保存的資料。本章節介紹的是 Vue 3 Store,用來管理應用程式的全域狀態,讓不同元件之間可以方便地共享和更新資料。但如果資料需要跨頁使用,建議將其存放於 localStorage ,以避免頁面重新整理後資料被清除。
目前官方推薦可以使用 Pinia 作為 Vue 3 的狀態管理工具,同時也可以透過 Vite 偵錯工具直接查看。以下先簡單說明一些基本常用功能。
來一個簡單的範例:查詢功能。當使用者開啟查詢介面時,需要先讀取選單的資料內容,而選單的資料內容來自 Backend API,如下圖的選單:
圖14-1:完成下拉選單,選單中資料為動態,由 Backend API 提供選單資料
前端專案建立一個 ItemStore.ts
SelectListItem
:定義選單資料的 DTO,包含文字、ID,以及是否被鎖定(Lock)。enumItemType
:列舉應用中可能存在的多種選單類型。companyOptions
:用來存放後端回傳的資料陣列物件。fetchOptions
:向後端發送請求以取得選單內容,接收參數為 itemType
,用以控制需要取得的選單類型。取得後端回應後,將資料存入對應的 Store Options 陣列中。例如,當參數 itemType
為 Location,則取回資料後會儲存至 LocationOptions[]
。import { defineStore } from 'pinia';
import { fetchWrapper } from '@/utils/helpers/fetch-wrapper';
export interface SelectListItem {
text: string;
value: string;
props: {
disabled: boolean;
};
}
export enum enumItemType{
//可能撈取不同的選單資料
company= 'company',
Production = 'Production',
Location = 'Location'
YN = 'YN',
}
export const useItemStore = defineStore('syscode', {
state: () => ({
companyOptions: [] as SelectListItem[], // 變數儲存資料
ProductionOptions: [] as SelectListItem[],
LocationOptions: [] as SelectListItem[],
YNOptions: [] as SelectListItem[]
}),
actions: {
async fetchOptions(itemType: enumItemType) {
const apiUri = `${import.meta.env.VITE_API_URL}/itemOptions?itemType=${itemType.toString()}`;//
const respData: SelectListItem[] = await fetchWrapper.get(apiUri) as SelectListItem[]; //回應資料轉 SelectListItem
const targetArray: string = itemType.toString() + 'Options'; // respData 回寫於 state companyOptions 中
(this as any)[targetArray] = await this.fetchSysCodeOptions(itemType);
},
},
});
至前端 Page 介面中 onMounted 生命週期時,透過調用 storeItemOptions.fetchOptions
的 actions,同步下拉公司選單的資料內容。
<script setup lang="ts">
import { ref, shallowRef, computed, onMounted } from 'vue';
import { useRoute } from 'vue-router';
const companyId = ref();
//store
import { useItemStore ,type SelectListItem ,enumItemType } from '@/stores/ItemStore';
const storeItemOptions = useItemStore (); // 取得ItemStore 中的 method 與state 中的變數
onMounted(() => {
await storeItemOptions.fetchOptions(enumItemType.company); //調用 ItemStore 中 actions
});
</script>
那如果有多不同的 Page 都會需要使用到該選單資料呢可以怎麼做?有一下兩個方式:
透過 Pinia 的 persist 套件將 Store 的狀態同步到 LocalStorage,但要特別注意,容量有限,LocalStorage 容量有限(約 5MB),不適合存大量資料。 (需要先安裝 pinia-plugin-persistedstate 並且於 main.ts 中註冊)
需要使用的 Page 需要重新 import Sotre,本次專案中我們大多使用此方式,重新取得最新的後台資料,某部分是為了需求面,因為選單資料希望可以動態與後端權限設計即時連。