iT邦幫忙

2023 iThome 鐵人賽

DAY 4
0

進入 vue3 後,多了一種跟 react 很像的資料管理方式 provide / inject ,和 vuex 相同的是他可以跨組件讀寫資料,但是和 vuex 不同的是跨組件的範圍僅限於 provide 註冊那一層的子組件,既然不能兩全我又一直學不好dispatch 和 mutations 的條件下學了 pinia。

#套件簡介

Pinia 是 vue 的存儲庫,它允許跨組件/頁面共享狀態,也就是一個獨立存在的,它保存狀態和業務邏輯,而不綁定到元件樹;換句話說,它是全局狀態的主人,它有點像一個組件,一直存在著,每個人都可以讀寫。
它包含三個概念:state、getters 和 actions,就像下圖所示,可以理解為這些概念相當於元件中的 data、computed 和 methods。
https://ithelp.ithome.com.tw/upload/images/20230904/20158099YbLhyAR8YB.png
(圖片來源:https://betterprogramming.pub/testing-pinia-is-vuex-out-43e0531824f5 )

優點:

  • 支持兩種語法創建 Store:Options API 和 Composition API
  • 刪除 mutations,只支持 state、getters、actions
  • 模塊化的設計,能很好支持代碼分割
  • 沒有嵌套的模塊,只有 Store 的概念
  • 完整的 TypeScript 支持

#安裝流程

如果在一開始使用 Create Vue 版本進行創建 vite 並同意安裝 Pinia,就可以跑安裝流程和開始方法,只需要到 package.json 找尋有沒有 Pinia 套件名稱和版本,有就代表安裝成功啦~可喜可賀~可喜可賀。
https://ithelp.ithome.com.tw/upload/images/20230904/20158099ucu6ypnV9l.png
如果沒有的話也沒關係直接使用 npm 安裝也可以

npm install pinia

#開始方法

這步驟是本來的專案沒有安裝 Pinia ,可以使用 npm 安裝,再到 main.js 檢查有沒有創建 Pinia 實例。

  1. createAppapp.mount('#app'); 前宣告定義,這是一個方法跟 Vue 建構環境方式很相近
  2. 在 Vue 環境中使用 Pinia 的方法:運用方式可以用 app.use() 直接引入套件名稱就可以使用
import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";

const app = createApp(App);

app.use(createPinia());
app.mount("#app");

官方文件說明
https://ithelp.ithome.com.tw/upload/images/20230904/20158099A60IUVd91O.png

#使用方法

Pinia 支持兩種語法創建 Store:Options API 和 Composition API,這裡主要介紹的是 Composition API 創建 store。
其實安裝完後,可以在右側選單內看到 store 資料夾,可以將建置的儲存資料檔案也放在這裡;點開資料夾可以看到預設的檔案 counter.js ,打開後內容如下,圖中附上各項說明。
https://ithelp.ithome.com.tw/upload/images/20230904/20158099hFY18XBDce.jpg
最重要的點如下:

  1. 建立 store 需使用到 Pinia 中 defineStore() 方法
  2. 原來 defineStore 定義是物件,現在改成帶參數,第一個參數為字串,是這個 store 的 id,可以隨意命名但需唯一;第二個參數是 composition API 函式內容
  3. 到這裡跟寫 Vue component 很像,只是如果用到 Vue3 <script setup> 語法糖就可以忽略 return,但是在 store 需要使用 return 把資料傳出去

#應用

- 元件調用 store 資料

Key:
元件如果需要使用 store 內的變數 ,可以 import 的方法引入調用,就算按鈕寫在父層,但是其他元件引用變數,也是可以運用 Pinia 受到 function 改變狀態把資料傳遞出來渲染在畫面上。

Example:

  1. 使在 App.vue 使用 store,用 import 的方法引入調用; → import { useCounterStore } from "./stores/counter.js";
  2. 宣告一個變數定義 store → const store = useCounterStore();
  3. console.log(store); 可以觀察一開始在 store 定義的資料和方法
    https://ithelp.ithome.com.tw/upload/images/20230904/20158099IYZ5k6nPtg.png
  4. 運用物件取值的方法可以調用 store 的資料和方法
    https://ithelp.ithome.com.tw/upload/images/20230904/20158099Yuv7Z0oalb.png

- axios 取回的資料存在 store 並調用

其實流程跟上述一樣,只是多示範一個從後端取到資料後存在 store ,然後一樣用 import 的方法引入調用
https://ithelp.ithome.com.tw/upload/images/20230904/20158099SYRXaAJgED.png
(畫面: https://youtu.be/giyELa7BdR0 )

- store 只能用物件取值引用嗎?

Store 在 import 引入調用並且宣告新變數後,只能用物件取值引用嗎?
其實,也可以用物件解構的方法,如此一來就不需要 store.xxx ,但是這裡要注意官方文件提醒:
https://ithelp.ithome.com.tw/upload/images/20230904/20158099OF4Ow7j5L0.png

Pinia 是把資料包起來也就是一個 proxy 物件,在外面把資料使用解構取出就不會是一個 proxy 物件,所以要解決這個問題可以使用 storeToRefs。

  • 方法類:可以直接解構
  • 資料類:透過 storeToRefs 解構

就像以下範例:如果要調用 store 的資料 count 和 travelList 直接解構會無法順利取得資料內容,但可以透過 storeToRefs 解構取得
https://ithelp.ithome.com.tw/upload/images/20230904/201580994SGml4vJVn.png

#Pinia 三劍客

最後用 Pinia 三劍客來結束這回合:

  • createPinia:在 main.js 創建 Pinia 實例
  • defineStore:在 xxx.js 定義 Store,每個 defineStore 都需要給一個 id
  • storeToRefs:由於 Store 是 proxy 物件,需要解構才能取出 State

#參考資料

學習 composition API 除了透過官網文件外,個人挺推薦以下視頻,說明很詳細且有範例說明也確實更清楚細節!


上一篇
魔法貓頭鷹 - axios
下一篇
巫師的布局 - Bootstrap (上)
系列文
Vue 元素美麗的轉變:前端小萌新勇闖套件的魔法陣30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言