vuex的辅助函数和基本属性使用的区别?

1. state

当我们需要读取state中的一个属性的时候,可以在组件内用computed来读取,这样当state变化的时候,组件就能实时改变
但是如果组件内需要用到多个state,每个状态都声明为计算属性的话重复代码就太多了,这是就需要用到辅助函数mapState来帮助我们生成计算属性

computed:{
    count(){
        //....
    },
    ...mapState({//结合展开运算符使用
        "count",//等同于  this.count :store.state.count
        count: state => state.count
    })
}
2. getter

当我们需要从store的state中派生出一些状态,比如一个list的长度,过滤掉某个state中的一些数据,可以在getter中定义这个派生状态

可以理解为getter就是state的计算属性,在组件中使用store.getters.count访问

getter和计算属性一样,返回值会根据他的依赖被缓存起来,只有当他的依赖值发生变化时才会重新计算
(computed和watch的区别?)

可以通过让getter返回一个函数来实现给getter传参

mapGetters辅助函数:将store中的getter映射到组件的计算属性中

3. mutation

更改vuex中store中的状态的唯一方法就是提交mutation。

mutation类似事件,每个mutation都有一个字符串的事件类型type(函数名)和一个回调函数,这个回调函数就是我们实际进行状态更改的地方,他会接受state作为第一个参数。

const mutations = {
    increment(state){
        state.count++
    }
}

但是我们修改state的时候,不能够直接调用mutation的回调函数increment(),需要使用store.commit(type)来调用相应的方法

我们也可以向store.commit中传入额外的参数,传递给mutation,即mutation的载荷 store.commit('increment', 10)

const mutations = {
    increment(state, n){
        state.count += n
    }
}

使用常量代替mutation事件类型,在各种Flux中非常常见,可以把这些常量单独放在一个文件中,这样整个app包含的mutation看起来非常清晰

//mutation-types.js
export const SOME_MUTATION = "SOME_MUTATION"
import Vuex from 'vuex'
import {SOME_MUTATION} from "mutation-types.js"

const store = new Vuex.store({
    state: {...},
    mutations: {
        //可以使用常量来作为函数名
        [SOME_MUTATION](state){
            //....
        }
    }
})

mutation必须是同步函数

在组件中提交mutation,可以使用this.$store.commit('xxx', payload)来提交mutation,或者使用mapMutations辅助函数将组件中的methods映射为store.commit来调用

4.action

action类似于mutation,但是不同的是action修改状态是通过提交mutation,而不是直接修改状态;action可以进行异步操作

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})

从上面例子我们可以看出,action函数接收一个和store实例具有相同方法和属性的context对象,因此我们可以调用context.commit()来提交mutation,或者通过context.getters和context.state来获取getters和state。

注意:context对象并不是store实例本身。

分发action,可以通过store.dispatch('increment')来触发
在组件中分发action,可以使用 this.$store.dispatch('increment'),或者使用mapActions将组件的methods映射为store.dispatch调用(需要在根节点注入store)

组合action:actions通常是异步的,怎么才能知道action什么时候结束呢?

  • 可以在action内返回promise,组件内使用this.$store.dispatch('increment').then(()=>{})
  • 利用async/await
actions: {
    async actionA({commit}){
        commit('gotData', await getData());//getData返回的是promise
    }
}
5.module

为了方便模块化开发,vuex允许我们将store分割成module,每个模块拥有自己的state,getter,mutation,action;