vue2.x之vuex module模块学习笔记(二)

一、文章参考

  1. https://vuex.vuejs.org/zh/guide/modules.html
  2. vue:vuex中mapState、mapGetters、mapActions辅助函数及Module的使用

问题描述

工作中,如果将所有的数据放到一个state中,数据量非常大就不便于维护,尤其是项目比较大分模块开发的时候,为了彼此不影响和便于维护,就需要加state通过命名空间隔离,因此大的项目就必须采用Vuex的模块命名。

学习条件

了解Vuex前面的基础 —— state、mutations、actions、getters

二、快速入门 vuex module模块

  1. 创建 one 和 two 两个 vuex module

one.js

export default {
  namespaced: true, // 需要命名空间隔离
  state () {
    return {
      name: 'one'
    }
  },
  getters: {
  },
  mutations: {
    changeName (state) {
      state.name = 'one-changeName'
    }
  },
  actions: {
  }
}

two.js

export default {
   state () {
      return {
         name: 'two'
      }
   },
   getters: {
   },
   mutations: {
      changeName (state) {
         state.name = 'two-changeName'
      }
   },
   actions: {
   }
}
  1. 将one和two两个vuex的模块引入进来
import { createStore } from 'vuex'
import one from './one'
import two from './two'

export default createStore({
  state () {
    return {
      name: 'xxx'
    }
  },
  getters: {
  },
  mutations: {
    changeName (state) {
      state.name = 'xxx-changeName'
    }
  },
  actions: {
  },
  modules: {
    one,
    two,
  }
})
  1. 工程中引入 vuex
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

const app = createApp(App)
app.use(router) // 加载路由
app.use(store) // 价值 vuex
app.mount('#app')
  1. 测试vuex的 module
<template>
  <div>store: {{ $store.state.name }}</div>
  <div>one.store: {{ $store.state.one.name }}</div>
  <div>two.store: {{ $store.state.two.name }}</div>
  <div>
    <button @click="changeName">改变name 的值</button>
  </div>
  <div>
    <button @click="changeModuleOneName">改变module one 的name 的值</button>
  </div>
</template>

<script>
export default {
  created() {},
  mounted() {},
  data() {
    return {};
  },
  methods: {
    changeName () {
      this.$store.commit('changeName')
    },
    changeModuleOneName () {
      this.$store.commit('one/changeName')
    }
  },
};
</script>

访问 state 中的数据结果如下:
在这里插入图片描述

改变 state 中的数据效果如下:

在这里插入图片描述

改变 module one state 中的数据效果如下:

在这里插入图片描述

结论:

  1. 如果使用 modules 定义vuex,则state 是被隔离的,例如: $store.state.two.name
  2. 如果module中没有定义 namespaced: true, 则 mutations 的方法是针对全范围所有定义mutations
  3. 如果定义了 namespaced: true,则需要添加 命名空间触发,例如this.$store.commit('one/changeName')

三、如何使用 module 拆分巨大的Vuex 对象

简单sample 说明

定义的vuex module要设置namespaced: true,

import state from './countState'
import mutations from './countMutations'
import getters from './countGetters'
import actions from './countActions'

export default {
    // 采用了命名空间,默认值为false
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}

自定义的Vuex module对象要挂载在 modules属性下

import countStore from './count/countIndex'
//创建store仓库暴露出去
export default new Vuex.Store({
	 modules: {
		 countModule: countStore
	 }
})

vuex模块文件管理

  1. 将一个模块设置为一个文件夹
  2. 文件夹下包含state、mutations、actions、getters,分别代表各自的数据
  3. 定义一个moduleIndex.js 文件,作为一个导出文件

state 文件

export default {
    count: 0
}

mutations 文件

export default {
    // state 是对应命名空间下面的state
    // paramObj 是传递过来的参数
    addCount: function (state, paramObj) {
        state.count = state.count + paramObj.step;
    },
    minuseCount: function (state, paramObj) {
        state.count = state.count - paramObj.step;
    }
}

actions 文件

export default {
    increment: function (context) {
        console.dir(context);
        debugger
        window.setTimeout(function () {
            context.commit({
                type: 'addCount',
                step: 2
            });
        }, 1000);
    },
    // {} 内的参数是 context 上下文中包含的对象
    reduce: function ({commit, dispatch, state, rootState, getters, rootGetters}) {
        window.setTimeout(function () {
            commit({
                type: 'minuseCount',
                step: 1
            });
        }, 1000);
    }
}

getters 文件

export default {
    getDoubleNum: function (state) {
        debugger
        return state.num * 2;
    }
}

countIndex 文件

import state from './countState'
import mutations from './countMutations'
import getters from './countGetters'
import actions from './countActions'

export default {
    // 采用了命名空间,默认值为false
    namespaced: true,
    state,
    getters,
    actions,
    mutations
}

针对模块的 mapState

methods: {
    // 添加
    addNum: function () {
        debugger
        this.$store.commit({
            type:'countModule/addCount',
            step: 1
        });
    },
    // 删除
    minuseNum: function () {
        this.$store.commit('countModule/minuseCount', {
            step: 2
        });
    },
    // 异步调用Action 触发事件
    addNumAction: function () {
        this.$store.dispatch('countModule/increment');
    },
    // // 异步调用Action 触发事件
    // minuseNumAction: function () {
    //     this.$store.dispatch('countModule/reduce');
    // }
    // 与上面等价
    ...mapActions('countModule',[
        'reduce'  //  this.$store.dispatch('countModule/reduce');
    ]) 
},

针对模块的 mapActions

computed: {
    myname: function () {
        return this.name + ' of hubei';
    },
    ...mapState({
        count: function (state) {
            console.dir(state);
            return state.countModule.count;
        }
    }),
    ...mapState('countModule',{
        countNew: 'count'
    }),
    doubleNum: function () {
        debugger
        return this.$store.state.countModule.count * 2;
    }
}

Vue界面关联

<template>
  <div>
      <div>{{myname}}</div>
      <div>count : {{count}}</div>
      <div>countNew : {{countNew}}</div>
      <div>double count: {{doubleNum}}</div>
      <div>
          <button @click='addNum'>同步 添加 </button>
      </div>
      <div>
          <button @click='addNumAction'>异步 添加 </button>
      </div>
      <div>
          <button @click="minuseNum">同步减少 </button>
      </div>
      <div>
          <!-- <button @click="minuseNumAction">异步减少 </button> -->
          <button @click="reduce">异步减少 </button>
      </div>
  </div>
</template>

<script>
// mapGetters 和 mapMutations 就是尝试了一下,关于有命名空间,尝试了多种办法,没有结果
import {mapState, mapGetters, mapActions, mapMutations} from 'vuex'
export default {
    data: function () {
        return {
            name: 'countModule/huangbiao'
        }
    },
    mounted: function () {
        console.dir(this);
        debugger
    },
    methods: {
        // 添加
        addNum: function () {
            debugger
            this.$store.commit({
                type:'countModule/addCount',
                step: 1
            });
        },
        // 删除
        minuseNum: function () {
            this.$store.commit('countModule/minuseCount', {
                step: 2
            });
        },
        // 异步调用Action 触发事件
        addNumAction: function () {
            this.$store.dispatch('countModule/increment');
        },
        // // 异步调用Action 触发事件
        // minuseNumAction: function () {
        //     this.$store.dispatch('countModule/reduce');
        // }
        // 与上面等价
        ...mapActions('countModule',[
            'reduce'  //  this.$store.dispatch('countModule/reduce');
        ]) 
    },
    computed: {
        myname: function () {
            return this.name + ' of hubei';
        },
        ...mapState({
            count: function (state) {
                console.dir(state);
                return state.countModule.count;
            }
        }),
        ...mapState('countModule',{
            countNew: 'count'
        }),
        doubleNum: function () {
            debugger
            return this.$store.state.countModule.count * 2;
        }
    }
}
</script>

<style>

</style>

三、文件夹的管理

  1. 目录接口如下图所示:
    在这里插入图片描述

  2. 各个模块的js结构如下
    在这里插入图片描述

  3. 使用index.js 将各个模块串联起来

import Vue from 'vue'
import Vuex from 'vuex'
import routes from '../router/routes'

const files = require.context('./modules', false, /\.js$/)
console.log("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%")
// ƒ webpackContext(req) {
// 	return __webpack_require__(webpackContextResolve(req));
// }
console.log(files)
// undefined
console.log(JSON.stringify(files))
// ["./location.js","./map.js","./pc-controller.js","./police-manage.js","./road-conf.js","./road-manage.js"]
console.log(JSON.stringify(files.keys()))
let modules = {}
files.keys().forEach(key => {
    if (key === './index.js') return
    // {default: {…}, __esModule: true}
    // default:
    //     actions: {fetchTaskList: ƒ, fetchRoadList: ƒ}
    //     mutations: {taskList: ƒ, roadList: ƒ, currentTaskIndexCode: ƒ, currentRoadIndexCode: ƒ, selectedShowRoadsIndexCode: ƒ}
    //     namespace: "road-manage"
    //     namespaced: true
    //     state: {…}
    console.log(files(key))
    let module = files(key).default
    modules[module.namespace] = module
})
Vue.use(Vuex)

export default new Vuex.Store({
    state: {},
    getters: {},
    mutations: {},
    actions: {},
    modules,
})

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值