vuex核心概念---action、getter、module

AAA晚来秋發表於2024-07-28

在vuex中還有其他三個概念,分別是action、getter、moduler,其實這三個概念多多少少大大小小都大同小異,接下來分別解釋。

1. action

前面提到在mutation是用作同步傳遞資料的,那麼非同步用誰呢?答案是action。為了方便devtools打個快照存下來,方便管理維護。所以說這個只是規範,而不是邏輯的不允許,只是為了讓這個工具能夠追蹤資料變化而已。
定義action

mutations: {
  changeCount (state, newCount) {
    state.count = newCount
  }
}


actions: {
  setAsyncCount (context, num) {
    // 一秒後, 給一個數, 去修改 num
    setTimeout(() => {
      context.commit('changeCount', num)
    }, 1000)
  }
},

呼叫action兩種方法

  1. 元件中透過dispatch呼叫
setAsyncCount () {
  this.$store.dispatch('setAsyncCount', 666)
}
  1. 輔助函式 -mapActions對映呼叫
import { mapActions } from 'vuex'
methods: {
   ...mapActions(['changeCountAction'])
   bntClick(){
   this.setAsyncCount()
   }
}

//mapActions對映的程式碼 本質上是以下程式碼的寫法
//methods: {
//  changeCountAction (n) {
//    this.$store.dispatch('changeCountAction', n)
//  },
//}

image

2. getter

類似於vue中的computed,進行快取,對於Store中的資料進行加工處理形成新的資料
具體操作類似於前幾種,這裡不做具體說明

3. modules

modules就是模組,這裡指的是vuex的模組,當專案太大時inde.js的各個核心就會太過臃腫,這時我們可以採用moudules分成一個一個小的模組
image
預設情況下,模組內部的 action 和 mutation 仍然是註冊在全域性名稱空間的——這樣使得多個模組能夠對同一個 action 或 mutation 作出響應。

如果希望你的模組具有更高的封裝度和複用性,你可以透過新增 namespaced: true 的方式使其成為帶名稱空間的模組。當模組被註冊後,它的所有 getter、action 及 mutation 都會自動根據模組註冊的路徑調整命名。

import axios from 'axios'
export default {
  namespaced: true,
  state () {
    return {
      list: []
    }
  },
  mutations: {
    updataList (state, payload) {
      state.list = payload
    },
    updatanewCount (state, obj) {
      const goods = state.list.find(item => item.id === obj.id)
      goods.count = obj.newCount
    }
  },
  actions: {
    async getdata (ctx) {
      const res = await axios.get('http://localhost:3000/cart')
      ctx.commit('updataList', res.data)
    },
    async updataCountAction (ctx, obj) {
      await axios.patch(`http://localhost:3000/cart/${obj.id}`, {
        count: obj.newCount
      })
      ctx.commit('updatanewCount', {
        id: obj.id,
        newCount: obj.newCount
      })
    }
  },
  getters: {
    totalCount (state) {
      return state.list.reduce((sum, item) => sum + item.count, 0)
    },
    totalPrice (state) {
      return state.list.reduce((sum, item) => sum + item.count * item.price, 0)
    }

  }
}

import { mapState } from 'vuex'
import { mapGetters } from 'vuex'
export default {

  name: 'App',
  created () {
    this.$store.dispatch('cart/getdata')
  },
  computed: {
    ...mapState('cart', ['list'])
	...mapGetters('cart', ['totalCount', 'totalPrice'])
  },
  components: {
    CartHeader,
    CartFooter,
    CartItem
  }
}

總結

image

相關文章