上周五刚发布一个线上版本,趁着新的需求和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调用接口进行各种操作。