对某项目中Vuex用法的分析

上周五刚发布一个线上版本,趁着新的需求和bug还没到来,决定分析一下正在维护的一个使用Vue 2.0 开发的后台管理系统中Vuex部分代码。这部分代码不是我写的,加上我一直在“使用”现成的而不是“搭建”项目,所以这是一个很好的提升。

使用npm安装vuex,在src文件下创建store文件夹,如下:

各文件/文件夹用途:

/store -- Vuex代码文件夹

/store/index.js -- 创建store实例,导出

/store/utils.js -- 各种工具,该项目utils.js文件创建了一个store构造函数,导出

/store/modules/ -- store中子模块

/store/modules/image.js -- j将modules中的各个文件导出的子模块汇总到一起,导出

/store/modules/image.js -- store中image子模块,与该项目中“图片库管理”模块对应

/store/index.js创建store实例导出后,在项目的入口文件main.js(或index.js)中引入,并注入到根节点中,这样一来所有组件都能获取store中的数据。另外,如果想在组件中使用mapMutations等辅助函数,需在该组件中手动从vuex中引入:

import { mapMutations, mapActions } from 'vuex'

/store/index.js:

import Vue from 'vue';
import Vuex from 'vuex';
import modules from './modules'; // 导入各个子模块
Vue.use(Vuex);

const store = new Vuex.Store({ // 创建store实例
  modules: {
    ...modules,
  },
});

export default store; // 导出store实例,在入口文件中注入根节点

/store/modules/index.js:

import home from './home'; // 导入各个子模块
import * as products from './products';
import * as user from './user';
import * as image from './image';
import * as facilitator from './facilitator';
import * as baseconfig from './baseconfig';
/*<状态注入>*/
export default { // 将各个子模块汇总成一个对象,也可以直接在store/index.js中完成
  /*<模块注入>*/
  ...products,
  ...facilitator,
  ...baseconfig,
  ...user,
  ...image,
  home,
};

/store/modules/image.js:

import Store from "../utils"; // 引入store模块构造函数

const imageCategory =  Store("image-category", {}, null); // 利用构造函数,每一个接口都生成一个store模块
const image =  Store("image", {}, null);
const imageUpload = Store("image/upload",{},null)
const skuImgs =  Store("sku/imgs",{},null)

export { // 导出各个store模块
    imageCategory,
    image,
    imageUpload,
    skuImgs
}

/store/utils.js:

// 生成一个公共的store
import fetch from '@/fetch';
import _ from '../utils/lodash';
import tools from '../utils/utils';
import config from '@/config/config';
/**
 *
 * @param {*} action  请求地址
 * @param {*} obj  参数对象,传入的参数可以替换默认store
 * @param {*} apiName  配合后端微服务 不同接口前缀
 */
//
const Store = (action, obj = {}, apiName = '') => { // 创建一个构造函数,用来生成store模块
  let api = `${config.getApi(apiName)}${action}`;
  const store = {
    namespaced: true, // 使用命名空间
    state: {
      // 异步loading控制
      loading: false,
      // 数据列表
      list: [],
      // 数据对象
      data: {},
      // 数据条数
      count: 0,
      url: action,
    },
    getters: {
      // 获取状态数据
      data(state, getters) {
        return state;
      },
    },
    mutations: {
      // 突变数据
      setOne(state, res) {
        if (res.code != 200) {
        } else {
          state.data = res.data;
        }
        state.loading = false;
      },
      // 突变列表
      setList(state, res) {
        if (res.code != 200) {
        } else {
          state.list = res.data.docs;
          state.count = res.data.count;
        }
        state.loading = false;
      },
      // 开启loading
      changeLoading(state, loading) {
        state.loading = loading;
      },
    },
    actions: {
      // 获取单条数据
      getByParams({ state, commit }, params = {}) {
        commit('changeLoading', true);
        return fetch
          .get(api, params)
          .then(res => {
            commit('setOne', res);
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },
      // 获取单条数据
      getById({ state, commit }, id) {
        commit('changeLoading', true);
        return fetch
          .get(`${api}/${id}`, {})
          .then(res => {
            commit('setOne', res);
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },

      // 获取列表数据
      getList({ state, commit }, params = {}) {
        commit('changeLoading', true);
        if (!params.pageSize) {
          Object.assign(params, { pageSize: 20 });
        }
        if (!params.pageNo) {
          Object.assign(params, { pageNo: 1 });
        }
        return fetch
          .get(api, params)
          .then(res => {
            commit('setList', res);
            return res;
          })
          .finally(one => {
            // debugger
            commit('changeLoading', false);
          });
      },

      // 新增数据
      post({ state, commit }, params = {}) {
        commit('changeLoading', true);
        return fetch
          .post(api, params)
          .then(res => {
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },

      // 修改数据
      put({ state, commit }, params = {}) {
        commit('changeLoading', true);
        return fetch
          .put(api, params)
          .then(res => {
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },

      // 删除数据
      delete({ state, commit }, id) {
        commit('changeLoading', true);
        return fetch
          .delete(`${api}/${id}`, {})
          .then(res => {
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },
      // 删除数据query
      deleteByQuery({ state, commit }, params) {
        commit('changeLoading', true);
        let query = tools.queryString(params);
        return fetch
          .delete(`${api}?${query}`, {})
          .then(res => {
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },
      // 批量删除数据
      deleteBatch({ state, commit }, ids) {
        commit('changeLoading', true);
        return fetch
          .delete(api, ids)
          .then(res => {
            return res;
          })
          .finally(one => {
            commit('changeLoading', false);
          });
      },
    },
  };

  const newStore = _.merge({}, store, obj);

  return newStore;
};

export default Store;

在入口文件中Vue实例的根节点注入store后,就可以在组件中获取Vuex中的各种数据了,也可以使用actions调用接口进行各种操作。

猜你喜欢

转载自www.cnblogs.com/zhengxj1991/p/9909209.html
今日推荐