乐趣区

关于vue.js:Vue中的Vuex二

小编明天持续和大家一起学习和探讨 Vuex,咱们书接上回,持续摸索 Vuex 的其余个性
三、Mutation
在上一篇文章中,咱们曾经晓得,对于 Vuex 中的数据,不能像 data 中的数据一样间接批改,那要对 State 中的数据批改的时候,要怎么做呢,Vuex 提供了 Mutation 形式进行对立批改,并且应用 state 作为第一个参数,就像这样

const store = new Vuex.Store({
  state: {count: 1},
  mutations: {increment (state) {
      // 变更状态
      state.count++
    }
  }
})

要触发这个函数,只须要这样就能够

store.commit('increment')

同样,咱们一样能够在提交的时候,多传递一个参数,也就是官网上说的
提交载荷(Payload),就像这样

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

store.commit('increment', 10)

实际上,咱们在应用 Mutation 第二个参数的时候,传递个对象,是平时更罕用的形式,同时,也能够传递更大量的数据信息,就像这样

// ...
mutations: {increment (state, payload) {state.count += payload.amount}
}
store.commit('increment', {amount: 10})

同样,官网还提出了“对象提交格调”,通过 type 作为作为提交对象的 key,对应触发 Mutation 中对应的办法,就像这样

store.commit({
  type: 'increment',
  amount: 10
})
mutations: {increment (state, payload) {state.count += payload.amount}
}

小编在这多说一点,针对对象,js 在新的语法中作了很多扩大,其中扩大运算符就是一个,能够合并属性一样的值,同样的,在 Linux 的一些配置文件中,应该也是应用了相似的思维。

state.obj = {...state.obj, newProp: 123}

在理论我的项目中,对于字符串,咱们很容易写错,在之前的文章中,小编提供了两种计划,一种是能够应用 es6 中的 Symbol 来实现,一种是能够定义常量来实现,这些在 Vuex 中也有相应的影子。

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

const store = new Vuex.Store({state: { ...},
  mutations: {
    // 咱们能够应用 ES2015 格调的计算属性命名性能来应用一个常量作为函数名
    [SOME_MUTATION] (state) {// mutate state}
  }
})

对于 Mutation,在组件中同样提供了简写形式,和后面的 mapGetters 相似,提供了 mapMutations 形式。

import {mapMutations} from 'vuex'

export default {
  // ...
  methods: {
    ...mapMutations(['increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

      // `mapMutations` 也反对载荷:'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
    ]),
    ...mapMutations({add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
    })
  }
}

还有一点值得注意,Mutation 必须是同步函数。为什么?请参考上面的例子:

mutations: {someMutation (state) {api.callAsyncMethod(() => {state.count++})
  }
}

当初设想,咱们正在 debug 一个 app 并且察看 devtool 中的 mutation 日志。每一条 mutation 被记录,devtools 都须要捕捉到前一状态和后一状态的快照。然而,在下面的例子中 mutation 中的异步函数中的回调让这不可能实现:因为当 mutation 触发的时候,回调函数还没有被调用,devtools 不晓得什么时候回调函数实际上被调用——本质上任何在回调函数中进行的状态的扭转都是不可追踪的。那对于异步函数,怎么解决呢,就到了 Vuex 中的 Actions
四、Actions
Action 相似于 mutation,不同在于:
Action 提交的是 mutation,而不是间接变更状态;

Action 能够蕴含任意异步操作。

咱们先来看一个简略的 action

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

咱们在散发 action 的时候,只需这样就能够了,

store.dispatch('increment')

而且在 action 外部,是容许进行异步操作的,这也是和 mutation 不一样的中央,就像这样

actions: {incrementAsync ({ commit}) {setTimeout(() => {commit('increment')
    }, 1000)
  }
}

同样 action 也反对同样的载荷形式和对象形式进行散发

// 以载荷模式散发
store.dispatch('incrementAsync', {amount: 10})

// 以对象模式散发
store.dispatch({
  type: 'incrementAsync',
  amount: 10
})

在组件中,也反对简写形式

import {mapActions} from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions(['increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

      // `mapActions` 也反对载荷:'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

同样,咱们在应用 action 的时候,也能够组合应用,并且联合 Promise 的个性,还有 async 和 await 写出更好更易保护,看着更难受的代码,就像这样

actions: {actionA ({ commit}) {return new Promise((resolve, reject) => {setTimeout(() => {commit('someMutation')
        resolve()}, 1000)
    })
  }
}
store.dispatch('actionA').then(() => {// ...})
actions: {
  // ...
  actionB ({dispatch, commit}) {return dispatch('actionA').then(() => {commit('someOtherMutation')
    })
  }
}

最初,如果咱们利用 async / await (opens new window),咱们能够如下组合
action:

// 假如 getData() 和 getOtherData() 返回的是 Promise

actions: {async actionA ({ commit}) {commit('gotData', await getData())
  },
  async actionB ({dispatch, commit}) {await dispatch('actionA') // 期待 actionA 实现
    commit('gotOtherData', await getOtherData())
  }
}

参考文献:https://vuex.vuejs.org/zh/
大家还能够扫描二维码,关注我的微信公众号,蜗牛全栈

退出移动版