更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutation 非常類似於事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。
接下來我們還是用上一篇文章在state中存放的count為例,來看利用Mutation修改state的count屬性。
利用commit來觸發mutation函數
在mutation函數中添加count的add函數
const mutations = { addNum (state) { state.num++ }, add (state) { state.count += 2 } } export default mutations
在組件中使用mutation進行實現疊加器
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="addCount">+ADD</button> </div> </template> <script> import store from '@/store/store' export default { computed: { count () { return this.$store.state.count } }, methods: { addCount () { store.commit('add') } } } </script>
Mutation的載荷(payload)
你可以向store.commit傳入額外的參數,即mutation的載荷(payload):我們還是以上面累加器的例子來實現mutation函數的傳參,來動態定義累加的數量。
在mutation.js中修改add方法
const mutations = { addNum (state) { state.num++ }, add (state, n) { state.count += n } } export default mutations
在組件中store.commit如何傳參
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="addCount">+ADD</button> </div> </template> <script> import store from '@/store/store' export default { computed: { count () { return this.$store.state.count } }, methods: { addCount () { store.commit('add', 5) } } } </script>
在mutation傳參(載荷)可以傳遞一個參數也可以傳遞一個對象。讓我們修改下上面的例子
mutation.js文件中修改如下
const mutations = { addNum (state) { state.num++ }, add (state, payload) { state.count += payload.amount } } export default mutations
組件中修改如下
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="addCount">+ADD</button> </div> </template> <script> import store from '@/store/store' export default { computed: { count () { return this.$store.state.count } }, methods: { addCount () { store.commit('add', { amount: 10 }) } } } </script>
在store.commit中可以進行對象風格的提交
依據上面的例子,我們將組件中內容修改如下
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="addCount">+ADD</button> </div> </template> <script> import store from '@/store/store' export default { computed: { count () { return this.$store.state.count } }, methods: { addCount () { store.commit({ type: 'add', amount: 8 }) } } } </script>
使用常量替代 Mutation 事件類型
使用常量替代mutation事件類型在各種Flux實現中是很常見的模式。這樣可以使 linter之類的工具發揮作用,同時把這些常量放在單獨的文件中可以讓你的代碼合作者對整個項目包含的mutation一目了然。這在在需要多人協作的大型項目中,這會很有幫助。
我們在store中新建mutation-types.js文件,文件內容如下
export const SOME_MUTATION = 'SOME_MUTATION'
在mutation.js文件內容如下
import { ADD } from './mutation-types' const mutations = { addNum (state) { state.num++ }, [ADD] (state) { state.count++ } } export default mutations
在組件中內容和之前一致
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="addCount">+ADD</button> </div> </template> <script> import store from '@/store/store' export default { computed: { count () { return this.$store.state.count } }, methods: { addCount () { store.commit('add') } } } </script>
在組件中使用this.$store全局屬性來觸發mutation函數
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="add">+ADD</button> </div> </template> <script> export default { computed: { count () { return this.$store.state.count } }, methods: { add () { this.$store.commit('add') } } } </script>
在組件中使用mapMutations輔助函數
<template> <div class="mutation"> <p>{{ count }}</p> <button @click="add">+ADD</button> </div> </template> <script> import { mapMutations } from 'vuex' export default { computed: { count () { return this.$store.state.count } }, methods: { ...mapMutations(['add']) } } </script>
Mutation一條重要的原則就是要記住 mutation 必須是同步函數