iT邦幫忙

2025 iThome 鐵人賽

DAY 14
0

Day13 提到 localStorage 的儲存方式,可於瀏覽器本地保存資料到使用者電腦,資料會永久保留,除非使用者主動清除。localStorage 適合保存需要跨頁或長期保存的資料。本章節介紹的是 Vue 3 Store,用來管理應用程式的全域狀態,讓不同元件之間可以方便地共享和更新資料。但如果資料需要跨頁使用,建議將其存放於 localStorage ,以避免頁面重新整理後資料被清除。

目前官方推薦可以使用 Pinia 作為 Vue 3 的狀態管理工具,同時也可以透過 Vite 偵錯工具直接查看。以下先簡單說明一些基本常用功能。

  • Store:類似一個全域物件,儲存資料(state)、方法(actions)、計算屬性(getters)
  • State:儲存資料的地方
  • Actions:用來執行異步操作或邏輯,並修改 state,通常放置後端需要呼叫到的API

來一個簡單的範例:查詢功能。當使用者開啟查詢介面時,需要先讀取選單的資料內容,而選單的資料內容來自 Backend API,如下圖的選單:
圖14-1:完成下拉選單,選單中資料為動態,由 Backend API 提供選單資料
圖14-1

建立 Store

前端專案建立一個 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);
    },
  },

});

編輯 vue

至前端 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>

Ending Remark

整理 Store與 vue 之間關係:

  • 資料流:Page → Store → Backend API → Store → Page。
  • 集中管理資料:Store 作為中介,管理和共享選單資料。
  • 利用生命週期觸發取得後端資料:利用 onMounted 確保頁面載入時取得最新資料。
  • UI 綁定自動更新:Vue 的雙向綁定讓頁面自動呈現最新資料。
    圖14-2
    圖14-2:前端選單資料流程 — Page 與 Store 與 Backend API 互動

store vs localStorage?

那如果有多不同的 Page 都會需要使用到該選單資料呢可以怎麼做?有一下兩個方式:

  1. 透過 Pinia 的 persist 套件將 Store 的狀態同步到 LocalStorage,但要特別注意,容量有限,LocalStorage 容量有限(約 5MB),不適合存大量資料。 (需要先安裝 pinia-plugin-persistedstate 並且於 main.ts 中註冊)

  2. 需要使用的 Page 需要重新 import Sotre,本次專案中我們大多使用此方式,重新取得最新的後台資料,某部分是為了需求面,因為選單資料希望可以動態與後端權限設計即時連。


上一篇
Day13 前端收到資料了,可以顯示於介面上囉
下一篇
Day15 Azure Pipeline 可以幫我們的事(一)
系列文
全端工程師團隊的養成計畫20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言