Bootstrap

vuex中commit

一、不使用模块的基础模式

vuex相关的文件夹,放在src下的store文件夹,里面有一个index.js文件,为vuex的入口,如果不使用模块,可以将所有相关代码写在index.js文件里面,下面是最基础的index.js文件演示:

import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { mainname: 'main' }, getters: { getMainname: (state) => { return state.mainname } }, mutations: { setMainname: (state, data) => { state.mainname = data } }, actions: { asyncSetMainname: ({ commit }, data) => { commit('setMainname', data) } } })

可以看到除了modules,其他属性都使用到了。其中mutations的方法就是直接修改state里面的变量,而actions是通过提交mutations去修改state,而不能直接修改stateactions中的方法的第一个参数是一个context上下文对象,可以通过context.commit提交mutations,上面的代码我将它解构。

下面是在组件中的操作:

获取state

this.$store.state.mainname // main

提交mutations

this.$store.commit('setMainname', 'main111') // 参数为mutations方法名,数据

提交actions

this.$store.dispatch('asyncSetMainname', 'main') // 参数为actions方法名,数据

获取getters

this.$store.getters.getMainname // main 一般写在计算属性中: computed:{ mainname() { return this.$store.getters.getMainname } }

这就是最基础的vuex用法。

二、使用模块

如果要将vuex拆分成几个模块,一般在index.js同级下新建一个modules文件夹,假如我现在拆分出一个叫user的模块,目录结构就变成:

vuex的子模块同样包含statemutationsactionsgetters这些属性,下面是user.js的代码:

const state = { username: 'user' } const getters = { getUsername: (state) => { return state.username } } const mutations = { setUsername: (state, data) => { state.username = data } } const actions = { asyncSetUsername: ({ state, commit }, data) => { commit('setUsername', data) } } export default { namespaced: true, state, getters, mutations, actions }

主体内容与入口文件index.js基本一致,最后将所有属性导出,同时要导出一个namespacedtrue,为开启命名空间,以免混乱,然后在index.js中将这个模块引入,下面是改动后的index.js:

import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' Vue.use(Vuex) export default new Vuex.Store({ state: { mainname: 'main' }, getters: { getMainname: (state) => { return state.mainname } }, mutations: { setMainname: (state, data) => { state.mainname = data } }, actions: { asyncSetMainname: ({ state, commit }, data) => { commit('setMainname', data) } }, modules: { user } })

现在实际上我的vuex是有两个模块,一个index主模块,一个user模块,那在组件中如何操作呢:

获取state
如果和上面的写法一样的话,获取的是index主模块中的state变量
如果想要获取user模块中的state,需要在后面加上模块名称

// 默认 this.$store.state.mainname // main // 获取子模块 this.$store.state.user.username // user

提交mutations
和获取state的逻辑一样,不加模块名称提交的是index中的mutations,要提交子模块中的mutations就得加上模块名

this.$store.commit('user/setUsername', 'user111') // 有点像url写法,在方法名称前加上模块名 如果不加模块名,会去index.js中找这个mutations方法,找不到就会报错 this.$store.commit('setUsername', 'user111') // 报错

提交actions,逻辑一样

this.$store.dispatch('user/asyncSetUsername', 'user111')

获取getters:

computed:{ mainname() { return this.$store.getters['user/getUsername'] } }

到这里vuex的基本操作就都说完了,包括不带模块的,带模块的,下面是使用vuex自带的map语法糖对操作进行简化。

使用vuex的map语法糖对操作进行简化

我们在组件中操作vuex,都得通过this.$store点点点,看起来比较繁琐,vuex提供了vuex和组件方法进行映射的语法糖,下面我演示一下这些map语法糖的写法:
在组件中,先从vuex中引入几个方法:

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

从名字就可以看出就是和mutationsactionsgetters在组件中做映射,下面先看不使用模块的情况,先从
mapMutations开始演示:
mapMutations是一个方法,返回一个对象,对象里面就是vuex里面的mutations方法,所以在和组件做映射时,要写在methods中,然后把这个对象解构:

methods: { // mapMutations可以接收一个数组为参数,数组项就是vuex里面mutations方法的名称 ...mapMutations([ 'setMainname' ]), 然后在别的方法中执行: fn() { this.setMainname('mainname1111') } }

上面的写法就相当于:

methods: { fn() { this.$store.commit('setMainname', 'main1111') } }

不仅可以映射到组件中的方法,还可以在组件中修改mutations方法的名称:

methods: { // 将mapMutations的参数从数组改成对象,key值为自定义的方法名,value中为原来mutations方法的名称 ...mapMutations({ setMainnamePro: 'setMainname' }), fn() { this.setMainnamePro('main1111') } }

mapActionsmapMutations用法一模一样,不改变actions方法名称时参数传数组,改变actions方法名称时参数传对象:

methods: { ...mapActions({ asyncSetMainnamePro: 'asyncSetMainname' }), fn() { this.asyncSetMainnamePro('main111') } } 相当于: methods: { fn() { this.$store.dispatch('asyncSetMainname', 'main111') } }

mapGetters道理也是一样,只不过是写在computed中:

computed: { ...mapGetters([ 'getMainname' ]) } 在别的地方用的话跟使用普通计算属性一样,注意后面没有括号: this.getMainname 同样可以修改名称,同样是参数把数组改成对象: computed: { ...mapGetters({ mainname: 'getMainname' }) } 在别的地方: this.mainname

几个map的基本用法就说完了,上面说的是不用模块的,也就是拿的都是index.js里面的属性,那如果要拿user模块里面的属性呢,其实也非常简单,只需要在几个map方法的第一个参数写上模块名称就可以,其他用法一模一样:

...mapMutations('user', [ 'setUsername' ]) ...mapActions('user', [ 'asyncSetUsername' ]) ...mapGetters('user', [ 'getUsername' ])

同样把第二个参数写成对象就可以自定义vuex里面方法的名称,用法与上面一样。

;