Vuex入门(4)—— 用Mutation管理状态

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

  关于vuex为什么这样做,先不要管,但请相信他这么做必然有很多的好处.在vue中,我们要修改data中的值,一般会怎么做.

this.count = 2 //count from 1 to 2,触发视图更新

   很简单,直接赋值,这也符合我们写代码的"一般规律",很舒服.但如果我们要修改vuex store中的状态值,我们就不能简单的通过赋值的方式来做了,如果你这样做,控制台便会报错.

this.$store.state.count = 2 //控制台打印错误

   当然vuex的state是可以更改的,不然就太睿智了,vuex提供了mutation来追踪你对state的值的操作,这肯定有什么好处在里面,暂时先把为什么放一边,先了解一下mutation的用法.

   Vuex 中的 mutation 非常类似于vue中的$emit事件,

   每个 mutation 都有一个字符串的事件类型 (type) ,相当于当前事件的唯一标识,以便于你用commit触发它.

   每个mutation都有一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数.同时他也支持额外参数的传入,额外参数的术语叫'载荷'.

  直接看代码和注释吧,不想过多解释这个

  1. //state.js
  2. let state = {
  3. count: 1,
  4. name: 'dkr',
  5. }
  6. export default state

 

  1. //mutation.js
  2. // 第一个参数默认接收state对象
  3. const increment = (state) => {
  4. state.count++
  5. }
  6. const decrement = (state) => {
  7. state.count--
  8. }
  9. //第二个参数接收'载荷'
  10. const add = (state, n) => {
  11. state.count += n
  12. }
  13. const fn = (state, json) => {
  14. state.name = json.first + json.second + state.name
  15. }
  16. export {increment, decrement, add, fn}

 

  1. <template>
  2. <div>
  3. <div>
  4. <button @click="decrement">-</button>
  5. <span>{{count}}</span>
  6. <button @click="increment">+</button>
  7. </div>
  8. <div style="margin-top:20px;">
  9. <button @click="add(1)">+1</button>
  10. <button @click="add(2)">+2</button>
  11. </div>
  12. <button style="margin-top:20px" @click = "changeName('my ','name is ')">{{name}}</button>
  13. </div>
  14. </template>
  15. <script>
  16. export default {
  17. computed: {
  18. count () {
  19. return this.$store.state.count
  20. },
  21. name () {
  22. return this.$store.state.name
  23. }
  24. },
  25. methods: {
  26. decrement () {
  27. this.$store.commit('decrement')
  28. },
  29. increment () {
  30. this.$store.commit('increment')
  31. },
  32. add (n) {
  33. // 你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
  34. this.$store.commit('add', n)
  35. },
  36. changeName (first, second) {
  37. // this.$store.commit('fn', {
  38. // 'first': first,
  39. // 'second': second
  40. // })
  41. // 上面的写法等同于下面,对象风格的提交方式,个人觉得上面的写法更清晰
  42. this.$store.commit({
  43. 'type': 'fn',
  44. 'first': first,
  45. 'second': second
  46. })
  47. }
  48. }
  49. }
  50. </script>

结果如下:

 

关于mutation的辅助函数,我这里提供一下上述代码的辅助函数写法,具体原理请看本系列第二篇文章,不想过多赘述.

  1. <template>
  2. <div>
  3. <div>
  4. <button @click="decrement">-</button>
  5. <span>{{count}}</span>
  6. <button @click="increment">+</button>
  7. </div>
  8. <div style="margin-top:20px;">
  9. <button @click="add(1)">+1</button>
  10. <button @click="add(2)">+2</button>
  11. </div>
  12. <button style="margin-top:20px" @click = "changeName({'first':'my ',second:'name is '})">{{name}}</button>
  13. </div>
  14. </template>
  15. <script>
  16. import { mapMutations } from 'vuex'
  17. export default {
  18. computed: {
  19. count () {
  20. return this.$store.state.count
  21. },
  22. name () {
  23. return this.$store.state.name
  24. }
  25. },
  26. // 辅助函数写法
  27. methods: {
  28. ...mapMutations({
  29. decrement: 'decrement',
  30. increment: 'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
  31. add: 'add',
  32. changeName: 'fn' // 将 `this.changeName(json)` 映射为 `this.$store.commit('fn', json)`
  33. })
  34. }
  35. }
  36. </script>
  37. <style>
  38. </style>

  

   最后说一下mutation的使用场景,mutation在使用的是请不要涉及任何异步操作,如果你想改变count的值,你通过mutation中的两个异步事件,都改变了这个状态值,你怎么知道什么时候回调和哪个先回调呢,因此mutation用于管理同步事件,如果有异步操作,请用action.

 下一章会玩一下action

  最近收到了阿里外包的offer,感觉有必要谈一下这件事,有时间把这个事情发到博客里供大家参考.

出处:https://blog.csdn.net/dkr380205984/article/details/82257792
posted @ 2021-02-08 21:56  十点书屋  阅读(119)  评论(0)    收藏  举报