vuex详细操作

只讲操作,不谈原理,适合工作用,不适合面试

一个最基本的vuex可以由一个js文件来实现,也是我们使用脚手架初始化vue项目默认生成的模式,一个最基本的vuex包括statemutationsactions,其中actions可以用来写异步代码,而mutations只能写同步代码,所以在一些更简单的项目中,actions都可以不用用到。但一个vuex的完整模块包括:statemutationsactionsgettersmodules,其中getters可以看作在vuex中的计算属性,modules就是一些子模块,在一些大型项目中对业务进行拆分。

image.png

下面我从最简单的模式到使用模块,再到使用vuex的map语法糖对vuex的操作进行演示一遍:

不使用模块的基础模式

先看看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的模块,目录结构就变成:

image.png

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里面方法的名称,用法与上面一样。

这就是本次超人鸭分享的vuex一些操作写法,主要是当用到模块与map语法糖时,在组件中如何操作。欢迎大家指教哦。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351