美文网首页vue
第四十一节:Vuex状态管理: Mutation的使用

第四十一节:Vuex状态管理: Mutation的使用

作者: 时光如剑 | 来源:发表于2020-06-14 21:31 被阅读0次

    1 Mutations使用

    1.1关于Mutations使用说明:
    1. 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation
    2. mutations非常类似于事件,都有一个字符串的事件类型type和一个回调函数handler
    3. 这个回调函数就是修改状态的地方,
    4. store对象提供了一个commit方法用来触发mutations中的事件, 有点类似于$emit
    1.2 定义与使用mutation
    1.2.1 定义mutations
    let store = new Vuex.Store({
        state:{
            count: 0
        },
    
        // 定义mutations
        mutations:{
            increment(){
                // console.log(this); //this 是store对象
                this.state.count++   // 修改状态中的数据
            }
        }
    })
    
    1.2.2 使用mutations函数修改数据
    // 组件中
    export default {
        // ...
        methods:{
            increment(){
                // 在组件中通过commit触发mutations中的函数
                this.$store.commit("increment")
    
            },
        }
    }
    

    2 关于mutations函数的参数

    2.1 mutations参数说明:
    1. mutations函数只接受两个参数
    2. mutations函数可以接受两个参数,第一个参数就是state状态,
    3. 第二个参数是在通过commit触发mutations函数时传递的载荷(Payload,其实就是自定义传参)
    2.2 mutations函数的第一个参数

    说明:

    1. 上一个示例中我们是采用了this.state.count++的方式修改数据的
    2. mutations函数接受的第一个参数就是state状态对象,因为我们可以直接通过state修改状态

    示例代码:

    let store = new Vuex.Store({
        state:{
            count: 0
        },
    
        // 定义mutations
        mutations:{
            increment(state){
                // mutations函数的第一个参数就是state对象
                // console.log(state);
                
                state.count++
            }
        }
    })
    
    2.3 mutations的第二个参数

    官网关于第二个参数的说法叫做提交载荷(Payload)

    也就是说我们在组件中使用commit触发mutations函数是,还可以传入额外的参数

    mutations

    let store = new Vuex.Store({
      state:{
        count: 0
      },
    
      // 定义mutations
      mutations:{
        increment(state, num){
            // 通过第二个参数指定state状态修改
          state.count += num
        }
      }
    })
    

    组件触发

    export default {
    
        // ...
        methods:{
            increment(){
                // 触发mutations函数是,指定额外的参数
                this.$store.commit("increment",2)
    
            },
    
        }
    
    }
    

    大多数情况下,载荷也就是第二个参数应该是一个对象,

    原因在于对象可以传递多个数据,如果传递普通类型的值只能传递一个

    export default {
    
        // ...
        methods:{
            increment(){
                // 触发mutations函数是,指定额外的参数
                this.$store.commit("increment",{
                    num: 2
                })
    
            },
    
        }
    
    }
    

    3. 关于Mutations的风格

    提交的另外一种风格:直接使用包含 type 属性的对象:

    示例代码如下

    export default {
    
        // ...
        methods:{
            increment(){
                // 触发mutations函数是,指定额外的参数
                this.$store.commit({
                    type:"increment",
                    num: 2
                })
    
            },
    
        }
    
    }
    

    此时Mutations函数不用做任何改变

    let store = new Vuex.Store({
        state:{
            count: 0
        },
    
        // 定义mutations
        mutations:{
            increment(state, payload){
                console.log(payload);
                /*
                {
                    type:"increment",
                    num: 2
                }
                */
                state.count += payload.num
            }
        }
    })
    

    会自动触发payload中type属性对应的mutations函数, commit参数对象整体就是Payload

    4. Mutation需要遵循Vue的响应规则

    既然 Vuex 的 store 中的状态是响应式的,那么当我们变更状态时,监视状态的 Vue 组件也会自动更新.

    因此Vuex中的mutation也需要Vue的响应规则

    4.1 触发响应的注意事项
    1. 最好提前在你的 store 中初始化好所有所需属性。
    2. 使用 Vue.set(obj, 'newProp', 123)方法新增对象的属性
    3. 使用新对象替换老对象的方式触发响应
    4.2 示例代码

    利用扩展运算来创建新对象替换老对象

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

    5. Mutation必须是一个同步函数

    5.1 同步函数说明
    1. 一条重要的原则就是要记住 mutation 必须是同步函数
    2. 如果mutation是一个异步函数, 异步修改状态,那么devtools将不能跟踪到数据的变化
    3. 因为devtools 都需要捕捉到前一状态和后一状态的快照
    4. 如果是异步函数将没发捕捉到快照信息
    5.2 示例代码
    let store = new Vuex.Store({
      state:{
        count: 0
      },
    
      // 定义mutations
      mutations:{
        increment(state, payload){
          
            //mutation中异步修改状态
          setTimeout(() => {
            state.count += payload.num
          },2000)
         
          console.log(this);
     
    })
    

    此时devtools中没发监听状态state的变化

    相关文章

      网友评论

        本文标题:第四十一节:Vuex状态管理: Mutation的使用

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