简介

模块化Vuex

为何会出现Vuex-Module

官方的解释
image.png

示例

store.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import { COUNT_OBJ, COUNT_MSG } from './mutation-types'
  4. import count from './modules/count'
  5. import studentList from './modules/studentList'
  6. Vue.use(Vuex)
  7. export default new Vuex.Store({
  8. // 启用严格模式,当在生产环境时取消严格模式
  9. strict: process.env.NODE_ENV !== 'production',
  10. // 储存信息的仓库
  11. state:{
  12. obj:{a:1},
  13. msg:'请输入值'
  14. },
  15. /**
  16. * 严格模式下,仓库可以修改状态值,但是视口不可以直接修改仓库的状态值,可以通过mutations修改仓库的状态值
  17. */
  18. mutations:{
  19. [COUNT_OBJ](state){
  20. // 不会触发响应式
  21. // state.obj.b = 3
  22. Vue.set(state.obj, 'b' , '3')
  23. },
  24. [COUNT_MSG](state,payload){
  25. state.msg = payload.value
  26. }
  27. },
  28. /**
  29. * 模块
  30. */
  31. modules:{
  32. count,
  33. studentList,
  34. }
  35. })

模块count.js

  1. import { COUNT_INCREMENT } from '../mutation-types'
  2. export default {
  3. state: {
  4. count: 0,
  5. },
  6. getters: {
  7. countDouble: (state,getters,rootState) => {
  8. console.log(rootState,"countDouble-rootDate")
  9. return state.count * 2
  10. },
  11. countAdd: state => num => state.count + num,
  12. },
  13. /**
  14. * 严格模式下,仓库可以修改状态值,但是视口不可以直接修改仓库的状态值,可以通过mutations修改仓库的状态值
  15. */
  16. mutations: {
  17. [COUNT_INCREMENT](state, payload) {
  18. state.count += payload.num;
  19. },
  20. },
  21. actions: {
  22. countIncrement(context, payload) {
  23. // 使用异步函数
  24. // setTimeout(() => {
  25. // context.commit(COUNT_INCREMENT, payload)
  26. // }, 1000);
  27. console.log(context.rootState,'actions-rootState')
  28. return new Promise((resolve,reject) =>{
  29. setTimeout(() => {
  30. console.log(context.state,'context.state')
  31. context.commit(COUNT_INCREMENT, payload)
  32. resolve()
  33. }, 1000);
  34. })
  35. }
  36. },
  37. }

模块studentList.js

  1. export default {
  2. state: {
  3. studentList: [],
  4. },
  5. getters: {
  6. studentLength: state => state.studentList.length,
  7. studentJuveniles: state => state.studentList.filter(ele => ele.age < 18)
  8. },
  9. }

效果图
image.png
从效果图中可以可看出count的值显示为啦一个对象,那吗测试getters
image.png
你会发现有一个神奇的现象,state显示都是对象,getters功能正常。看下面

Vuex-module 的缺陷

当使用Vuex-module时。会将state就行模块化,而getters还会继续留在根模块上示意图如下image.png
如何从上图看不出啥,当不使用Vuex-module的vueX状态的示意图
image.png
对比两张图你会发现,使用Vuex-module会将state中的模块值封装成对象

解决办法

使用count.count

  1. <button @click="handleClick">{{count.count}}</button>

效果图
image.png
如果想正常使用mapState 可以使用命名空间

命名空间

命名空间简介

官方解释
image.png

开启命名空间

  1. import { COUNT_INCREMENT } from '../mutation-types'
  2. export default {
  3. // 开启命名空间
  4. namespaced: true,
  5. state: {
  6. count: 0,
  7. },
  8. getters: {
  9. countDouble: (state,getters,rootState) => {
  10. return state.count * 2
  11. },
  12. countAdd: state => num => state.count + num,
  13. },
  14. /**
  15. * 严格模式下,仓库可以修改状态值,但是视口不可以直接修改仓库的状态值,可以通过mutations修改仓库的状态值
  16. */
  17. mutations: {
  18. [COUNT_INCREMENT](state, payload) {
  19. state.count += payload.num;
  20. },
  21. },
  22. actions: {
  23. countIncrement(context, payload) {
  24. // 使用异步函数
  25. // setTimeout(() => {
  26. // context.commit(COUNT_INCREMENT, payload)
  27. // }, 1000);
  28. return new Promise((resolve,reject) =>{
  29. setTimeout(() => {
  30. context.commit(COUNT_INCREMENT, payload)
  31. resolve()
  32. }, 1000);
  33. })
  34. }
  35. },
  36. }

此时你会发现控制台告诉你getters中的属性与方法都不存在
image.png
查看vuex的状态为
image.png
你会发现getters中启用命名空间的模块都以对象的形式保存根模块上

如何使用辅助函数

  1. //使用辅助函数时需要将第一参填写为空间名前缀
  2. ...mapState('模块名',['count']),

如何使用使用this.$stroe上的值

  1. // 需要将其空间前缀名/ + 属性名
  2. this.$store.dispatch('count/countIncrement',{
  3. num:10
  4. }).then(res =>{
  5. alert("运行成功")
  6. })

模块局部状态

官方文档:https://vuex.vuejs.org/zh/guide/modules.html