「後端小夥伴來學前端了」Vuex進階操作,讓你的代碼更加高效(簡稱如何學會偷懶 【手動狗頭】)

  • 2021 年 11 月 25 日
  • 筆記

學妹手機里的美照

前言

前一篇寫了Vuex基本使用,用起來還稍稍有些繁瑣,代碼有很多
冗餘的地方,這篇就帶着大家用更簡單的方式來使用Vuex(其實就是怎麼更好的偷懶,用更少的代碼來完之前的事情)

進入正文….


一、mapGetters 方法

在我們之前要取出store中的getters,在組件中是需要$store.getters.bigSum 才能取到,為了方便會寫成計算屬性

bigSum(){
    return this.$store.getters.bigSum
}

一個兩個還能接受,但是如果有很多的,代碼會顯得十分冗餘。不太合適,作為一名合格的程序員,偷懶是必備的哈。

我們能想到的,前輩們都已經考慮到了。所以就有了mapGetter輔助函數。

mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性:

//第一步得先引入
import {mapGetters} from 'vuex'

// 第二步 寫在計算屬性中
computed:{
    // 之前的寫法
    // bigSum(){
    //   return this.$store.getters.bigSum
    // }
  
    //藉助mapGetters生成計算屬性:bigSum(對象寫法)
    ...mapGetters({bigSum:'bigSum'}),

    //藉助mapGetters生成計算屬性:bigSum(數組寫法)
    // ...mapGetters(['bigSum']),
},

實現效果都是一樣的。

如果有多個值需要映射的話, ...mapGetters({bigSum:'bigSum'},{xxxx:'xxxxx'}), 或者...mapGetters(['bigSum','xxxx'])都是可以的,極大的壓縮了代碼。

二、mapState方法

之前要從store 中取得 state 的話,有下面兩種方式

  1. $store.state.sum 或者是下面這種計算屬性的方式,但是仍要我們自己寫。
  computed:{
    sum(){
      return this.$store.state.sum
    }
  },

自動生成方法,和上面的那個mapGetter 是一樣的

// 引入的時候多引入一個 mapState  
import {mapGetters,mapState} from 'vuex'

// 計算屬性
computed:{
    // sum(){
    //   return this.$store.state.sum
    // }
    //藉助mapState生成計算屬性:sum(對象寫法)
    ...mapState({sum:"sum"}),
   //藉助mapState生成計算屬性:sum(數組寫法)
    ...mapState(['sum']),
},

即使是多個也會非常方便,自動生成是真的香(😁)

三、mapActions方法

用於幫助我們生成與actions對話的方法,即:包含$store.dispatch(xxx)的函數

之前的寫法

methods: {
    increment(){
        this.$store.dispatch("increment",1)
    }
}

在按鈕調用處是如下方式調用的

<button @click="increment">點擊自加</button>

自動生成的寫法

methods:{

    //靠mapActions生成:increment(對象形式)
    ...mapActions({increment:'increment'})
    //靠mapActions生成:increment(數組形式)	
    // .mapActions(['increment'])

    // 	increment(){
    //       this.$store.dispatch("increment",1)
    //     }
    //使用方式 這個時候 組件內定義的方法不能像之前一樣 重名了,得改一下
    zijia(){
        // 調用的時候 可以直接this  不用寫  $store.dispatch  這個了  後面跟參數即可 
        this.increment(1);
    }

}

四、mapMutations方法

用於幫助我們生成與mutations對話的方法,即:包含$store.commit(xxx)的函數

methods:{
    
    //靠mapActions生成:increment、decrement(對象形式)
    ...mapMutations({INCREMENT:'INCREMENT'}),
    
    //靠mapMutations生成:JIA、JIAN(對象形式)
    ...mapMutations(['INCREMENT']),

    // 使用方式
   zijia(){
      // 之前的方式    this.$store.commit("INCREMENT",1)
  	  this.INCREMENT(1)
    }   
}

五、模塊化+命名空間

  1. 目的:讓代碼更好維護,讓多種數據分類更加明確。

  2. 原因:項目應用中存在多個模塊,多個模塊下又分為多個組件,我們將store分模塊,管理數據起來更加的方便,也更易進行數據的維護和擴展。

  3. 修改store.js

    const countAbout = {
      namespaced:true,//開啟命名空間
      state:{x:1},
      mutations: { ... },
      actions: { ... },
      getters: {
        bigSum(state){
           return state.sum * 10
        }
      }
    }
    
    const personAbout = {
      namespaced:true,//開啟命名空間
      state:{ ... },
      mutations: { ... },
      actions: { ... }
    }
    
    const store = new Vuex.Store({
      modules: {
        countAbout,
        personAbout
      }
    })
    
  4. 開啟命名空間後,組件中讀取state數據:

    //方式一:自己直接讀取
    this.$store.state.personAbout.list
    //方式二:藉助mapState讀取:
    ...mapState('countAbout',['sum','school','subject']),
    
  5. 開啟命名空間後,組件中讀取getters數據:

    //方式一:自己直接讀取
    this.$store.getters['personAbout/firstPersonName']
    //方式二:藉助mapGetters讀取:
    ...mapGetters('countAbout',['bigSum'])
    
  6. 開啟命名空間後,組件中調用dispatch

    //方式一:自己直接dispatch
    this.$store.dispatch('personAbout/addPersonWang',person)
    //方式二:藉助mapActions:
    ...mapActions('countAbout',{incrementOdd:'jiaOdd',incrementWait:'jiaWait'})
    
  7. 開啟命名空間後,組件中調用commit

    //方式一:自己直接commit
    this.$store.commit('personAbout/ADD_PERSON',person)
    //方式二:藉助mapMutations:
    ...mapMutations('countAbout',{increment:'JIA',decrement:'JIAN'}),
    

六、項目結構

vuex並沒有強制大家使用什麼樣的結構,更多的是一種規則、習慣、建議。

大部分時候Vuex會遵守以下幾個規則:

  1. 應用層級的狀態應該集中到單個 store 對象中。
  2. 提交 mutation 是更改狀態的唯一方法,並且這個過程是同步的。
  3. 異步邏輯都應該封裝到 action 裏面。

另外就是,當我們的項目變得十分龐大的時候,我們可以將action、mutation 和 getter 分割到單獨的文件。引入,最後直接導出 store即可,之後再在main.js中引入。

對於大型應用,vuex建議大致如下的項目結構。(我們在平時開發時也應該要有這種分模塊的思想,無論在前端還是後端都應如此,因為這會讓接手你項目的人更為輕鬆)

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API請求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我們組裝模塊並導出 store 的地方
    ├── actions.js        # 根級別的 action
    ├── mutations.js      # 根級別的 mutation
    └── modules
        ├── cart.js       # 購物車模塊
        └── products.js   # 產品模塊

後語

大家一起加油!!!如若文章中有不足之處,請大家及時指出,在此鄭重感謝。

紙上得來終覺淺,絕知此事要躬行。

大家好,我是博主寧在春主頁

一名喜歡文藝卻踏上編程這條道路的小青年。

希望:我們,待別日相見時,都已有所成