Vuex入门简单示例(四)

前言

我想写一系列关于Vuex的入门文章,我是看着vuex官网文档,结合自己从零搭建的vue项目来实践vuex的知识。

Vuex入门系列:

 

 

本文涉及知识点:

  1. vuex之mutation
  2. vuex之mutation提交载荷(传参)
  3. vuex之mapMutations

 

vuex官方文档对mutations的描述

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

你不能直接调用一个mutation handler。这个选项更像是事件注册。要唤醒一个mutation handler,你需要以相应的type调用store.commit方法

看之前文章中的示例代码,

src/components/Login.vue

      // 修改isLogin状态
      this.$store.commit('changeLogin', true)
      // 修改username状态
      this.$store.commit('changeUsername', this.username)
      // 修改password状态
      this.$store.commit('changePassword', this.password)

 

提交载荷

你可以向store.commit传入额外的参数,即mutation的载荷.

这里做一个用到mutation的小栗子

在store.js的state里添加一个count状态

src/store.js

    state: {
     // ...
      count: 0
    },

mutations里面添加2个操作count的方法,一个用来增加,一个用来重置

src/store.js

    mutations: {
      // ...
      addCount(state, n) {
        state.count += n
      },
      resetCount(state, data) {
        state.count = data;
      }
    }

 

回到Home.vue使用count

在计算属性的mapState里添加count

  computed: {
    // ...
    ...mapState({
      isLogin: state => state.isLogin,
      username: state => state.username,
      password: state => state.password,
      count: state => state.count
    }),
    // ...
  },

在methods里添加两个方法唤醒mutations

  methods: {
    add () {
      this.$store.commit('addCount', 1)
    },
    reset () {
      this.$store.commit('resetCount', 0)
    }
  }

最后在template里添加count相关内容

    <hr>
    <div>
      <h3>mutation载荷</h3>
      <span>{{count}}</span> | <button @click="add">+1</button> | <button @click="reset">重置</button>
    </div>

两个按钮分别调用add和reset事件

运行测试一下

 

 

使用对象形式的载荷也能实现这种效果

很多时候,尤其是当数据比较复杂,使用对象形式的载荷会更好。

修改store.js mutations addCount和resetCount事件

src/store.js

      addCount(state, payload) {
        state.count += payload.n
      },
      resetCount(state, payload) {
        state.count = payload.data;
      }

修改Home.vue methods add和reset方法

src/components/Home.vue

    add () {
      this.$store.commit('addCount', {
        n: 1
      })
    },
    reset () {
      this.$store.commit('resetCount', {
        data: 0
      })
    }

效果一样。多学会一种写法总是好的。

 

对象风格的mutation

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

结合本例,修改Home.vue

  methods: {
    add () {
      this.$store.commit({
        type: 'addCount',
        n: 1
      })
    },
    reset () {
      this.$store.commit({
        type: 'resetCount',
        data: 0
      })
    }
  }

效果一样

 

Mutation需遵守Vue的相应规则

以下摘自vuex官网

既然Vuex的store中的状态是响应式的,那么当我们变更状态时,监视状态的Vue组件也会自动更新。这也意味着Vuex中的mutation页需要与使用Vue一样遵守一些注意事项

  1. 最好提前在你的store中初始化好所需属性
  2. 当需要在对象上添加新属性时,你应该
    • 使用Vue.set(obj, 'newProp', 123),或者
    • 以新对象替换老对象。例如,

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

 

 Mutation必须是同步函数

这个没有可以测试的接口,所以跳过吧。

 

在组件中提交Mutation

你可以在组件中使用this.$store.commit('xxx')提交mutation

 

mapMutations辅助函数

现在我们把示例修改一下,尽量用上mapMutations辅助函数

store.js不用动

在Home.vue导入mapMutations

import { mapState, mapGetters, mapMutations } from 'vuex'

在methods里面用对象展开运算符添加...mapMutations,先说第一种方式

  methods: {
    ...mapMutations(['addCount', 'resetCount'])
  }

这里,如果是不带参数的mutation,可以直接调用,this.addCount,this.resetCount.

如果是带参数的,则另外写一个方法,来调用this.addCount(arg)

src/components/Home.vue

  methods: {
    ...mapMutations(['addCount', 'resetCount']),
    add () {
      this.addCount({n: 1})
    },
    reset () {
      this.resetCount({data: 0})
    }
  }

注意这个例子里的n和data,这两个名称是和store.js里面写的对应的。

src/store.js

      addCount(state, payload) {
        state.count += payload.n
      },
      resetCount(state, payload) {
        state.count = payload.data
      }

预览一下,效果一致。

第二种写法,mapMutations里面放一个对象

src/components/Home.vue

  methods: {
    ...mapMutations({
      theAdd: 'addCount',
      theReset: 'resetCount'
    }),

    add () {
      this.theAdd({n: 1})
    },
    reset () {
      this.theReset({data: 0})
    }
  }

效果一致

 

参考文档:Vuex官方中文文档 

 

posted on 2019-08-15 18:13  独自去流浪  阅读(675)  评论(0编辑  收藏  举报