[Vuex系列] - Mutation的具體用法

王小端coder發表於2019-04-23

更改 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 必須是同步函式

一、[Vuex系列] - 初嘗Vuex第一個例子

二、[Vuex系列] - 細說state的幾種用法

三、[Vuex系列] - Mutation的具體用法

四、[Vuex系列] - getters的用法

五、[Vuex系列] - Actions的理解之我見

六、[Vuex系列] - Module的用法(終篇)



相關文章