技术控

    今日:43| 主题:49507
收藏本版 (1)
最新软件应用技术尽在掌握

[其他] Vuex下Store的模块化拆分实践

[复制链接]
我宣你 发表于 2016-12-2 15:14:09
40 0

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
前言

  最近的项目用到了 vue.js + vuex + vue-router 全家桶,版本为 >2.0,在搞Store的时候发现,圈子里大部分关于vuex的文章都是比较基础的Demo搭建方式,很少有涉及到比较复杂的模块化拆分的Store实践,而且事实上也有朋友在实践中问到过这方面的内容,vuex自身提供了模块化的方式,因此在这里总结一下我自己在项目里的心得。
  模块化拆分

  vue.js的项目文件结构在这里就不说了,大家可以通过    vue-cli初始化项目,脚手架会为你搭建一个start项目的最佳实践。  
  默认你已经搭架好了一个项目,而且需要建立或者已经是一个复杂的Store,但是还没有进行模块拆分,你可以尝试对其进行模块拆分,当然在一开始你不必一定需要这么做。
  1. 安装Vuex,建立文件结构

  在项目根目录下安装vuex:
  1. npm install vuex -S
复制代码
安装完毕后,在项目的    src文件夹下新建一个    store文件夹,并且分别在其中新建    modules,    actions,    mutations,    getters,    constants子文件夹和一个    index.js文件。  
  目录结构如下:
  1. --demo
  2. -----build
  3. -----config
  4. -----node_modules
  5. -----src
  6. --------assets
  7. --------components
  8. --------store
  9. -----------actions
  10. --------------aAction.js
  11. --------------bAction.js
  12. --------------cAction.js
  13. -----------constants
  14. --------------types.js
  15. -----------getters
  16. --------------aGetter.js
  17. -----------modules
  18. --------------aModules.js
  19. --------------bModules.js
  20. --------------cModules.js
  21. --------------index.js
  22. -----------mutations
  23. --------------aMutation.js
  24. --------------bMutation.js
  25. --------------cMutation.js
  26. -----------index.js
  27. --------App.vue
  28. --------main.js
  29. -----static
  30. -----utils
  31. -----test
  32. -----index.html
复制代码
好了,基本的文件结构大概就是上面:point_up_2:这样的。
  2. 编写模块A

  在编写模块之前,首先设定一些type类,例如:
  types.js

  1. module.exports = keyMirror({
  2.     FETCH_LIST_REQUEST: null,
  3.     FETCH_LIST_SUCCESS: null,
  4.     FETCH_LISR_FAILURE: null
  5.    
  6. })
  7. function keyMirror (obj) {
  8.   if (obj instanceof Object) {
  9.     var _obj = Object.assign({}, obj)
  10.     var _keyArray = Object.keys(obj)
  11.     _keyArray.forEach(key => _obj[key] = key)
  12.     return _obj
  13.   }
  14. }
复制代码
     上面:point_up_2:自己实现keyMirror的方法,大家也可以使用下面这个包:
    github.com/STRML/keyMirror    keyMirror的作用就是下面这个一个形式��,作用其实也不是很大:
    Input: {key1: null, key2: null}
    Output: {key1: key1, key2: key2}
    actions/aAction.js

  1. import { FETCH_LIST_REQUEST, FETCH_LIST_SUCCESS, FETCH_LISR_FAILURE } from  '../constants/types'
  2. import { toQueryString } from '../../utils'
  3. import axios from 'axios'
  4. export const fetchListAction = {
  5.     fetchList ({ commit, state }, param) {
  6.         commit(FETCH_LIST_REQUEST)
  7.         axios.get('http://youdomain.com/list')
  8.           .then(function (response) {
  9.             commit(FETCH_LIST_SUCCESS, {
  10.                 data: response.data
  11.             })  
  12.             console.log(response);
  13.           })
  14.           .catch(function (error) {
  15.             commit(FETCH_LIST_FAILURE, {
  16.                 error: error
  17.             })
  18.             console.log(error);
  19.           });
  20.     }
  21. }
复制代码
getters/aGetter.js

  1. export const = fetchListGetter = {
  2.     hotList (state) {
  3.         return state.fetchList.data.slice(0, 10)
  4.     }
  5. }
复制代码
mutations/aMutation.js

  1. import { FETCH_LIST_REQUEST, FETCH_LIST_SUCCESS, FETCH_LISR_FAILURE } from  '../constants/types'
  2. export const fetchListMutation = {
  3.     [FETCH_LIST_REQUEST] (state) {
  4.         state.isFetching = true
  5.     },
  6.     [FETCH_LIST_SUCCESS] (state, action) {
  7.         state.isFetching = false
  8.         state.data = action.data
  9.         state.lastUpdated = (new Date()).getTime()
  10.     },
  11.     [FETCH_LIST_FAILURE] (state, action) {
  12.         state.isFetching = false
  13.         state.error = action.error
  14.     }
  15. }
复制代码
modules/aModule.js

  1. import { fetchListAction } from '../actions/aAction'
  2. import { fetchListGetter } from '../getter/aGetter'
  3. import { fetchListMutation } from '../mutation/aMutation'
  4. export const list = {
  5.     state: {
  6.         isFetching: false,
  7.         data: []
  8.     }
  9.     actions: fetchListAction,
  10.     getters: fetchListGetter,
  11.     mutations: fetchListMutation
  12. }
复制代码
modules/index.js

  1. import { list } from './aModule'
  2. module.exports = {
  3.     list: list
  4. }
复制代码
3. 挂载store

  index.js

  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. import createLogger from 'vuex/dist/logger'
  4. import { list } from './modules'
  5. Vue.use(Vuex)
  6. const store = new Vuex.Store({
  7.   modules: {
  8.     list: list
  9.    
  10.   },
  11.   plugins: [createLogger()],
  12.   strict: process.env.NODE_ENV !== 'production'
  13. })
  14. if (module.hot) {
  15.   module.hot.accept(['./modules'], () => {
  16.     const newMutations = require('./modules').default
  17.     store.hotUpdate({
  18.       mutations: newMutations
  19.     })
  20.   })
  21. }
  22. export default store
复制代码
4. store注入vue实例

  main.js

  1. ····
  2. import store from './store'
  3.   ····
  4. var vue = new Vue({
  5.   store,
  6.   ····
  7. })
  8. vue.$mount('#app')
复制代码
5. 在Component中使用

  Vue 提供了组件中使用的    mapState,    mapAction,    mapGetter方法,因此可以很方便的调用。  
  Example.vue

  1. --demo
  2. -----build
  3. -----config
  4. -----node_modules
  5. -----src
  6. --------assets
  7. --------components
  8. --------store
  9. -----------actions
  10. --------------aAction.js
  11. --------------bAction.js
  12. --------------cAction.js
  13. -----------constants
  14. --------------types.js
  15. -----------getters
  16. --------------aGetter.js
  17. -----------modules
  18. --------------aModules.js
  19. --------------bModules.js
  20. --------------cModules.js
  21. --------------index.js
  22. -----------mutations
  23. --------------aMutation.js
  24. --------------bMutation.js
  25. --------------cMutation.js
  26. -----------index.js
  27. --------App.vue
  28. --------main.js
  29. -----static
  30. -----utils
  31. -----test
  32. -----index.html0
复制代码
复用模块

    模块化拆分之后可以实现较为复杂的数据流,特别地,如果对action和mutation稍加改造,就可以复用模块:
    比如我们在Example.vue中发起Action:
    Example.vue

  1. --demo
  2. -----build
  3. -----config
  4. -----node_modules
  5. -----src
  6. --------assets
  7. --------components
  8. --------store
  9. -----------actions
  10. --------------aAction.js
  11. --------------bAction.js
  12. --------------cAction.js
  13. -----------constants
  14. --------------types.js
  15. -----------getters
  16. --------------aGetter.js
  17. -----------modules
  18. --------------aModules.js
  19. --------------bModules.js
  20. --------------cModules.js
  21. --------------index.js
  22. -----------mutations
  23. --------------aMutation.js
  24. --------------bMutation.js
  25. --------------cMutation.js
  26. -----------index.js
  27. --------App.vue
  28. --------main.js
  29. -----static
  30. -----utils
  31. -----test
  32. -----index.html1
复制代码
在上面的例子中,我们在组件挂载完成之后发起了一个fetchList的action,并添加了一个名为    week的参数,接下来对aAction.js做一些修改。  
  actions/aAction.js

  1. --demo
  2. -----build
  3. -----config
  4. -----node_modules
  5. -----src
  6. --------assets
  7. --------components
  8. --------store
  9. -----------actions
  10. --------------aAction.js
  11. --------------bAction.js
  12. --------------cAction.js
  13. -----------constants
  14. --------------types.js
  15. -----------getters
  16. --------------aGetter.js
  17. -----------modules
  18. --------------aModules.js
  19. --------------bModules.js
  20. --------------cModules.js
  21. --------------index.js
  22. -----------mutations
  23. --------------aMutation.js
  24. --------------bMutation.js
  25. --------------cMutation.js
  26. -----------index.js
  27. --------App.vue
  28. --------main.js
  29. -----static
  30. -----utils
  31. -----test
  32. -----index.html2
复制代码
请求成功之后,在 commit()中加入了一个request的参数,这样Mutation就可以从里面获取相应的参数,最后对aMutation做一些修改。
  mutations/aMutation.js

  1. --demo
  2. -----build
  3. -----config
  4. -----node_modules
  5. -----src
  6. --------assets
  7. --------components
  8. --------store
  9. -----------actions
  10. --------------aAction.js
  11. --------------bAction.js
  12. --------------cAction.js
  13. -----------constants
  14. --------------types.js
  15. -----------getters
  16. --------------aGetter.js
  17. -----------modules
  18. --------------aModules.js
  19. --------------bModules.js
  20. --------------cModules.js
  21. --------------index.js
  22. -----------mutations
  23. --------------aMutation.js
  24. --------------bMutation.js
  25. --------------cMutation.js
  26. -----------index.js
  27. --------App.vue
  28. --------main.js
  29. -----static
  30. -----utils
  31. -----test
  32. -----index.html3
复制代码
state加入了[action.request],以区分不同的接口数据。
  完成以上修改后,只需要在组件调用相应的action时加入不同的参数,就可以调用相同类型但数据不同的接口。
  总结

  以上是我在Vuex实践中总结的一些东西,分享给大家,如果有不合理或者错误:x:的地方,也希望各位老司机不吝赐教:pray::pray:,有机会多交流。
    微信号:pasturn
    Github:      https://github.com/pasturn
友荐云推荐




上一篇:Dorothy2:一个开源的僵尸网络分析框架
下一篇:AI用于医学影像,你需要知道这些 | 硬创公开课
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表