mutations

作者: 未vv | 来源:发表于2020-03-26 11:22 被阅读0次

    Vuex store状态的更新唯一方式:提交(commit) mutations

    Mutations主要包括两部分:
    1.字符串的事件类型(type)
    2.一个回调函数,该回调函数的第一个参数就是state,还可以传入第二个参数(mutation的载荷 Payload )


    image.png
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      state: {
        counter: 10
    
      },
      mutations: {
        incrementCount(state, count) {
          state.counter += count;
        }
      }
    
    })
    export default store
    
    <template>
      <div id="app">
        <h2>{{$store.state.counter}}</h2>
        <button @click="addCount(5)">+5</button>
        <button @click="addCount(10)">+10</button>
      </div>
    </template>
    
    <script>
    export default {
      name: 'App',
      data() {
        return {}
      },
      methods:{
        addCount(count){
          this.$store.commit('incrementCount',count)
        }
      }
    }
    </script>
    
    

    对象风格的提交方式

    提交 mutation 的另一种方式是直接使用包含 type 属性的对象:

    methods:{
        // addCount(count){
        //   this.$store.commit('incrementCount',count)
        // }
    
        //对象风格的提交方式
        addCount(count){
          this.$store.commit({
            type:'incrementCount',
            count
          })
        }
      }
    

    注意mutation的第二个参数是对象

      mutations: {
        // incrementCount(state, count) {
        //   state.counter += count;
        // }
    
        //对象提交风格对应的mutation
        incrementCount(state, payload) {
          console.log(payload) //{type: "incrementCount", count: 5}
          state.counter += payload.count
        }
    
      }
    

    使用常量替代 Mutation 事件类型

    mutations-types.js

    export const INCREMENT_COUNT = 'incrementCount'
    

    App.vue

    <template>
      <div id="app">
        <h2>{{$store.state.counter}}</h2>
        <button @click="addCount(5)">+5</button>
        <button @click="addCount(10)">+10</button>
      </div>
    </template>
    
    <script>
    import {INCREMENT_COUNT} from './store/mutations-types'
    
    export default {
      name: 'App',
      data() {
        return {}
      },
      methods:{
        addCount(count){
          this.$store.commit(INCREMENT_COUNT,count)
        }
      }
    }
    </script>
    

    store

    import Vue from 'vue'
    import Vuex from 'vuex'
    import {
      INCREMENT_COUNT
    } from './mutations-types'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      state: {
        counter: 10
      },
      mutations: {
        [INCREMENT_COUNT](state, count) {
          state.counter += count
        }
      }
    
    })
    export default store
    

    Mutation 必须是同步函数

    如果是异步,当 mutation 触发的时候,回调函数还没有被调用,devtools 不知道什么时候回调函数实际上被调用,导致无法追踪状态。

    <template>
      <div id="app">
        <h2>{{$store.state.student}}</h2>
        <button @click="changeStudent">改变student中的name</button>
      </div>
    </template>
    
    <script>
    
    
    export default {
      name: 'App',
      data() {
        return {}
      },
      methods:{
        changeStudent(){
          this.$store.commit('updateStudent')
        }
      }
    }
    </script>
    
    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
      state: {
        student: {
          age: 18,
          name: 'haha'
        }
      },
      mutations: {
        updateStudent(state) {
          setTimeout(() => {
            state.student.name = 'aa'
          }, 1000)
        }
      }
    
    })
    export default store
    

    上面的代码 由于mutations里有异步操作,devtools无法追踪,视图上,student对象的name属性


    image.png

    如何处理异步问题?使用actions

    mapMutations辅助函数

    import Vue from 'vue'
    import Vuex from 'vuex'
    
    Vue.use(Vuex)
    
    const store = new Vuex.Store({
    
      state: {
        counter: 10
      },
      mutations:{
        increment(state){
          state.counter += 1
        }
      }
    })
    export default store
    
    <template>
      <div id="app">
       <h2>{{counter}}</h2>
       <button @click="increment">增加</button>
      </div>
    </template>
    
    <script>
    import { mapState,mapMutations } from 'vuex'
    export default {
      name: 'App',
      data () {
        return {}
      },
      computed:{
         // 映射 this.myCount 为 this.$store.state.counter
        ...mapState(['counter'])
      },
      methods:{
        // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
        ...mapMutations(['increment'])
      }
    }
    </script>
    

    mapMutations也支持对象形式的映射

    相关文章

      网友评论

          本文标题:mutations

          本文链接:https://www.haomeiwen.com/subject/mufayhtx.html