7-4 Element UI及Vuex-分模块组织Vuex

目录:

  • 简介
  • 组织vuex项目结构
  • 具体示例

一、简介

 之前我们把 state、actions、mutations等所有的东西,都是写在 store.js里面的,也就是说使用单一状态数,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store对象就有可能变的相当臃肿。为了解决以上的文艺,Vuex允许我们将store分割成  模块(module)。每个模块拥有自己的state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割,官网解释:Module

二、组织Vuex项目结构

Vuex 并不限制你的代码结构。但是,它规定了一些需要遵守的规则:项目结构

  1. 应用层级的状态应该集中到单个 store 对象中。

  2. 提交 mutation 是更改状态的唯一方法,并且这个过程是同步的。

  3. 异步逻辑都应该封装到 action 里面。

只要你遵守以上规则,如何组织代码随你便。如果你的 store 文件太大,只需将 action、mutation 和 getter 分割到单独的文件。

对于大型应用,我们会希望把 Vuex 相关代码分割到模块中。下面是项目结构示例:

├── index.html
├── main.js
├── api
│   └── ... # 抽取出API请求
├── components
│   ├── App.vue
│   └── ...
└── store
    ├── index.js          # 我们组装模块并导出 store 的地方
    ├── actions.js        # 根级别的 action
    ├── mutations.js      # 根级别的 mutation
    └── modules           # 根级别的是公共的,modules里面的是各个模块的,分为多个模块
        ├── cart.js       # 购物车模块
        └── products.js   # 产品模块

请参考购物车示例,这些官方网站都有,只不过我在这边copy了一下,并且稍微加了一些补充。

三、具体示例

3.1、初始化项目

#初始化项目
>vue init webpack-simple vuex-demo2
....

#进入项目
>cd vuex-demo2

#安装依赖包
>npm install

#安装vuex插件
> npm install vuex -S

3.2、项目目录结构

|-vue-demo2 //项目名
    |-....
    |-src
        |-index.js
     |-mutation-types.js  //用来配置mutions的类型,我们定义为一个常量
        |-getters.js
        |-mutations.js  //此次没有用到mutations,所以不做编辑
        |-modules     //分为多个模块,每个模块都可以拥有自己的state、getters、actions、mutations
            |-user.js
            |-...
    |-.....

3.3、思路图

3.4、编辑main.js

import Vue from 'vue'
import App from './App.vue'

import store from './store/index.js'  //导入store对象

new Vue({
  el: '#app',
  render: h => h(App),
  store  //注册store
});

3.5、编辑modules-> user.js

/**
 *  用户模块
 */

import types from '../mutations-types'   //导入常量提交类型


//1.定义属性(数据)
let state={
  count:6
};
//2.定义getters
let getters = {
  count(state){ //参数state就是上面的state
    return state.count;
  }
};


//3.定义actions,要执行的操作,如流程判断,一部请求等
const actions = {
  increment({commit,state}){ //es6的语法
    commit(types.INCREMENT);  //在常量中(mutation-type.js)定义突变的名字
  },
  decrement({commit,state}){
    if(state.count>10){
      commit(types.DECREMENT);
    }
  }
};


//4.定义mutations处理状态(数据)的改变
const mutations = {
  [types.INCREMENT](state){  //我们可以通过使用ES6的语法[type.INCREMENT](state){},而不能直接使用type.INCREMENT(state){}的方式
    state.count++;
  },
  [types.DECREMENT](state){
    state.count--;
  }
};


export default {
  state,
  getters,
  actions,
  mutations
};

 3.6、编辑getters.js

/**
 *  定义公共的getters,如果其他模块也想用的话,可以放在公用的getters.js中
 */
const getters = {
  isEvenOrOdd(state){
    return state.user.count%2 == 0?'偶数':'奇数'; //state.user区别是哪个模块的count变量
  }
};

//别的js模块想用,必须先 导出
export default getters;

3.7、编辑 actions.js

/**
 * 定义公共的actions,这个动作是公共的,根一级的actions
 */
import types from './mutations-types'

const actions = {
  incrementAsync({commit,state}){
    //异步操作
    let p = new Promise((resolve,reject) => {
      setTimeout(() => {
        resolve();
      },3000);
    });
    p.then(()=> {
      commit(types.INCREMENT); //这边我们通过调用mutation-types.js常量来提交
    }).catch(() => {
      console.log('异步操作');
    });
  }
};


export default actions;

3.8、 编辑mutation-types.js

说明:我们在提交的时候一般使用常量,所以这边我们专门定义一个模块来定义常量,=>使用常量替代 Mutation 事件类型

/**
* 定义类型常量
*/

const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';

export default {
  INCREMENT,
  DECREMENT
}

3.9、编辑index.js

/**
 * 在index.js中要把所有的模块进行导出,是一个出口文件
 */

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex);

import getters from './getters.js'
import actions from './actions.js'
import user from './modules/user.js'

export default new Vuex.Store({
  getters,
  actions,
  modules:{  //模块的方式导入,因为Vuex.store没有user选项,只有module选项
    user
  }
})

3.10、编辑App.vue

<template>
  <div id="app">
    <button @click="increment">增加</button>
    <button @click="decrement">减少</button>
    <button @click="incrementAsync">增加</button>
    <!--获取数据-->
    <p>当前数据为:{{count}}</p>
    <p>{{isEvenOrOdd}}</p>
  </div>
</template>

<script>
import {mapGetters,mapActions} from 'vuex'

export default {
  name: 'app',
  //方式2:通过mapGetters、mapActions访问
   computed:mapGetters([
    'count', //对应的store.js中的getters中的count()方法
     'isEvenOrOdd'
  ]),
  methods:mapActions([
    'increment',
    'decrement',
    'incrementAsync'
  ])
}
</script>

实现的效果:

  

当前数据为:14

偶数

posted @ 2020-03-23 10:45  帅丶高高  阅读(467)  评论(0)    收藏  举报