yaoningvital / blog

my blog
31 stars 4 forks source link

Vuex--state、getters、mutations、actions的定义和调用 #163

Open yaoningvital opened 5 years ago

yaoningvital commented 5 years ago

一、state

1、定义

const store = new Vuex.Store({
  state: {
    count: 0
  }
})

2、读取

就是说在组件中有一个属性,比如count,它的值是读取的store中state里的count的值,也就是说,组件中的一个属性订阅了全局的store。那么组件中的count怎么读取store中的值呢?

(1)直接读取(this.$store.state.XXX)

computed: {
    count () {
         return  this.$store.state.count
    }
  }

(2)利用mapState

export default {
  // ...
  computed: mapState({
    count: state => state.count,

    // 同 `state => state.count`
    countAlias: 'count',

    // 要访问组件自己的属性 localCount,必须使用正常的函数,不能使用箭头函数
    countPlusLocalState (state) {
      return state.count + this.localCount
    }
  })

说明 以上两种方式,都需要满足下面两个前提: 1、首先要在根Vue实例中注入 store,这里的this.$store才会指向store。 2、组件的属性必须写在computed中,是一个计算属性。

二、getters

getters相当于store中的计算属性。

1、定义

const store = new Vuex.Store({
  state: {...} ,
  getters: {
    doneTodos: (state, getters, rootState, rootGetters)=> {
      return state.todos.filter(todo => todo.done)
    }
  }
})

2、读取

(1)直接读取 (this.$store.getters.XXX)

computed: {
  doneTodosCount () {
    return this.$store.getters.doneTodosCount
  }
}

(2)利用mapGetters

computed: {
    // mix the getters into computed with object spread operator
    ...mapGetters([
      'doneTodosCount',
      'anotherGetter',
      // ...
    ])
  }

三、mutations

mutations中定义的是一个一个的方法,这些方法是用来修改state的。mutations中只能放同步的操作,不能放任何异步的操作。

1、定义

const store = new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    increment (state, payload) {
      // mutate state
      state.count++
    }
  }
})

2、调用mutations中的方法

(1)直接调用

store.commit('increment')

也可以带一个参数 payload:

store.commit('increment', payload)

(2)利用 mapMutations

export default {
  // ...
  methods: {
    ...mapMutations([
      // 这个表示调用组件内的 this.increment()方法,实际上会去调用store中的mutations中的increment方法(this.increment()  =>  this.$store.commit('increment')  )
      'increment', // map `this.increment()` to `this.$store.commit('increment')`

      // `mapMutations` also supports payloads:
      'incrementBy' // map `this.incrementBy(amount)` to `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({
      add: 'increment' // map `this.add()` to `this.$store.commit('increment')`
    })
  }
}

四、actions

1、定义

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    },
    incrementAsync({state, getters, commit, dispatch}, payload){
       setTimeout(() => {
           commit('increment')
       }, 1000)
      ...
    }
  }
})

2、调用

(1)直接调用

store.dispatch('increment')

也可以带payload:

// dispatch with a payload
store.dispatch('incrementAsync', {
  amount: 10
})

// dispatch with an object
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

(2)利用mapActions

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // map `this.increment()` to `this.$store.dispatch('increment')`

      // `mapActions` also supports payloads:
      'incrementBy' // map `this.incrementBy(amount)` to `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // map `this.add()` to `this.$store.dispatch('increment')`
    })
  }
}