1. 程式人生 > >對某專案中Vuex用法的分析

對某專案中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呼叫介面進行各種操作。