Skip to content
    在 Opshell 的 Blog 中:
  • 目前已分享 70 篇文章
  • 還有 114 個坑正在填補中
  • 已有: Loading 次觀看
  • 已有: Loading 個人來過
✍️ Opshell
📆 Last Updated:8/23/2024Created:2022/09/24
👀 已被閱讀: Loading

[Day24]:Vuex安裝&設定

Day24 Banner

Vuex 設定

Vuex是一個專為Vue.js開發的狀態管理模式 + 套件他集中儲存、管理App中的所有組件狀態──────────────────── By Vuex


目標:安裝、設定Vuex


過程:

  • SCSS

    沒事,就是前兩天忘了裝:

    shell
     yarn add sass sass-loader -D

    然後Ops有個全域共用的scss,需要引用一下 設定vite.config.ts

    typescript
     export default defineConfig({
       // ... 省略一堆
    
       css: {
          preprocessorOptions: {
             scss: { // 設定全域SCSS
                additionalData: '@import "@/assets/scss/stylesheet.scss";'
             }
          }
       }
     }

    ※ 在main.js中不要再次引用stylesheet.scss文件,不然會報重複引用錯誤。


  • Vuex

    進入今天的重點:

    shell
     yarn add vuex@next -D

    目前Vuex沒有為this.$store提供宣告檔案,所以沒辦法開箱即用。 所以我們需要做個宣告檔案所幸Vuex有提供文件教學, 讓我們一步一步來:


  • 1. Vue 中 $store 属性的型別宣告

    ./src/types/裡新增一個vuex.d.ts(vuex宣告檔案), 宣告ComponentCustomProperties(組件自訂屬性)

    typescript
     // vuex.d.ts
     import { Store } from 'vuex'
    
     declare module '@vue/runtime-core' {
       // 宣告vuex內部的 store state
       interface State {
          count: number
       }
    
       // 宣告 `this.$store` 型別
       interface ComponentCustomProperties {
          $store: Store<State>
       }
     }

  • 2. useStore composition(組合式) API 型別宣告

    使用composition(組合式)API寫 Vue 組件的時候, 會希望useStore回傳型別化的store, 為了達成這個效果,必須做下面這些設定:

    • 定義型別化的InjectionKey

      使用Vue的InjectionKey接口和自己的store型別宣告來定義 key

      typescript
       // store.ts
       import { InjectionKey } from 'vue'
       import { createStore, Store } from 'vuex'
      
       // 宣告 store state 型別
       export interface State {
         count: number
       }
      
       // 宣告 injection key
       export const key: InjectionKey<Store<State>> = Symbol()
      
       export const store = createStore<State>({
         state: {
            count: 0
         }
       });
    • store安裝到 Vue app時,提供型別化的InjectionKey

      typescript
       // main.ts
       import { createApp } from 'vue';
       import './style.css';
       import App from './App.vue';
       import { store, key } from './store';
      
       const app = createApp({});
      
       // 傳入 Injection key
       app.use(store, key);
       app.mount('#app');
    • 最後,型別化的InjectionKey傳給useStore

      typescript
       // 要使用的組件
       import { useStore } from 'vuex'
       import { key } from './store'
      
       export default {
         setup () {
            const store = useStore(key)
      
            store.state.count // 型別為 number
         }
       }

  • 3. 簡化 useStore 用法

    但是,利用InjectionKey傳給useStore,這件事, 很快就會變成工廠流水線,讓你一直重複。 依照自動化原則,來定義自己的composition(組合式) API 来檢索型別化的store

    typescript
    // store.ts
     import { InjectionKey } from 'vue'
     import { createStore, useStore as baseUseStore, Store } from 'vuex'
    
     export interface State {
       count: number
     }
    
     export const key: InjectionKey<Store<State>> = Symbol()
     export const store = createStore<State>({
       state: {
          count: 0
       }
     })
    
     // 定義自己的 `useStore` composition(組合式) API
     export function useStore () {
       return baseUseStore(key)
     }

    现在,我們不用提供Injection key型別宣告就可以直接得到型別化的store

    typescript
     // vue 组件
     import { useStore } from './store'
    
     export default {
       setup () {
          const store = useStore()
    
          store.state.count // 型別為 number
       }
     }

小結:

按照官方提供的流程一步步來, 感覺並不是很複雜, 但真正的問題總是在實作時出沒, 在明天正式改寫store的時候見真章~ 大家晚安~

Released under the MIT License.