初見狀態管理工具 Vuex (1) 初步接觸與安裝導入


Posted by Calon on 2022-04-25

Vuex 官網

前言

現在有比 Vuex 更精簡的狀態管理工具 Pinia,官方也推薦使用。
Pinia 支援 Options APIComposition API,並且完整支援 TypeScript。

但考慮到工作上可能會遇到還是使用 Vuex 的公司或狀況,所以決定學習 Vuex。


Vuex 是什麼?

首先為什麼需要 Vuex?
Vue.js 的最小功能單位是「元件」,每個元件都有自己的狀態(state)、模板(view)以及邏輯(actions),並且會希望元件可以高度重複利用。但隨著專案的成長擴大,元件的增加,容易造成元件與元件之間相互依賴性提高,這時為了保持元件在「高內聚,低耦合」(high cohesion, low coupling)的狀態,也就是元件間的依賴程度降低,每個元件都是獨立的狀態。這樣一來,元件就可以根據不同的程式去被改變與修改,並且不會因此影響到元件本身的功能。

舉例來說,購物車的商品資料可能會在導覽列、產品列表頁面、單一產品頁面、購物車頁面、結帳頁面、完成訂單頁面使用和修改,如果今天在產品列表頁面將購物車商品的數量加 1,這時所有用到購物車商品資料的元件都需要一一去做更新,也就是可能需要將資料一一向上 emit 到根元件,再從根元件向下 props 到每個需要更新的子元件去,這樣不僅增加了元件間的耦合性,也造成日後要維護時的難度。

而 Vuex 就是來解決這個問題的,它是專門為 Vue.js 設計的狀態管理庫,採用集中式存儲管理應用的所有元件狀態。
也就是把共同狀態全都集中到一個 store 去管理,並且只能使用指定的方法去修改裡面資料。

註:如果是小型網站可以單純使用 store 模式

開始之前我們在稍微來看一下放在 Vuex 官方文件的圖:

Vuex 是作為一個「單一資訊來源(Single Source of Truth)」,也就是將共用資料集中到一個地方去做管理,所以一個應用程式裡只能有一個 store 實體。

Vuex 的主要結構為:

  • state:存放資料狀態的物件,類似元件中的 data
  • actions:存放方法的物件,除了改變資料狀態以外的方法都會放到這裡,類似 methods
  • mutations:負責存放會改變資料的方法
  • getters:取得資料狀態的方法,類似 coumputed


安裝 Vuex

用 CDN 引入:

<script src="/path/to/vuex.js"></script>

使用 npm:

npm install vuex@next --save

或是 yarn:

yarn add vuex@next --save

如果是用 Vue CLI:

  1. 新啟動的專案可以在安裝選項那邊將 Vuex 選起來。
  2. 如果想再已建立好的專案上安裝可以使用下列指令:
    vue add vuex
    


開始使用 Vuex

在安裝好之後我們可以在自己的專案上導入 Vuex。

  1. CDN 的方式
import { createApp } from 'vue'
import { createStore } from 'vuex'

const store = createStore({
  state: {
  },
  mutations: {
  },
});

const app = createApp({ /* 根元件 */ });

app.use(store);
app.mount('#app');

我們可以用 store.state 去取得 store 裡面的資料,並用 store.commit 來觸發 mutations 去更新 state。

  1. Vue CLI
    如果是使用 Vue CLI 安裝的話,會發現它已經很貼心的幫你在 main.js 引入以及新增了一個 store 目錄,在目錄裡面有一個 index.js 打開如下:
import { createStore } from 'vuex';

export default createStore({
  state: {
  },
  gatters: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  },
});

在 Vue 元件中我們可以使用 this.$store 來訪問 store 實體,例如:

methods: {
  increment() {
    this.$store.commit('incrementt');
    console.log(this.$store.state.count);
  },
},

當然我們也可以選擇不用 use 來導入 store,改成在需要使用的元件內 import 就好:

<template>
  ...
</template>

<script>
import store from '@/store';

export default {
  methods: {
    increment() {
      store.commit('increment');
    },
  },
};
</script>

引入 store 的方式就變得跟使用 CDN 一樣。


參考資料

#Vue.js #vuex







Related Posts

CH 11 類別(class)

CH 11 類別(class)

How to make a Line chatbot with AWS Lambda

How to make a Line chatbot with AWS Lambda

關於 JavaScript 的提升 (Hoisting)

關於 JavaScript 的提升 (Hoisting)


Comments