1.封装的axios请求---http.js文件
import axios from 'axios';
import mv from '@/main';
import qs from 'qs';
/**
* 请求token配置
*/
import axios from 'axios';
import mv from '@/main';
import qs from 'qs';
/**
* 请求token配置
*/
const http = axios.create();
http.interceptors.request.use(config => {
const accessToken = window.sessionStorage.getItem('access_token');
// 递归删除前后空格
const enumTrim = target => {
let result;
if (target === null) return target;
if (typeof target === 'string') {
result = target.trim();
result = result.replace(/[;]/g, '');
} else if (typeof target === 'object') {
result = target instanceof Array ? [] : {};
for (let i in target) {
if (Object.prototype.hasOwnProperty.call(target, i)) {
result[i] = enumTrim(target[i]);
}
}
} else {
result = target;
}
return result;
};
// 定义header权限
config.headers['Authorization'] = `Bearer ${accessToken}`;
// query请求参数格式化
config.paramsSerializer = params => {
let p = enumTrim(params);
p = qs.stringify(p, {
encode: false,
arrayFormat: 'indices',
});
p = p.replace(/\[/g, '%5B');
p = p.replace(/\]/g, '%5D');
return p.replace(/%5B(\D*?)%5D/g, '.$1');
};
// body请求参数格式化
config.transformRequest = (data, head) => {
if (data instanceof FormData) {
return data;
} else {
head['Content-Type'] = 'application/json;charset=utf-8';
const newData = enumTrim(data);
return JSON.stringify(newData);
}
};
return config;
}, err => {
return Promise.reject(err);
});
http.interceptors.response.use(res => {
const data = res.data;
const { msg, code } = data;
if (code === 1) {
mv.$alert(msg, {
type: 'error',
});
return Promise.reject(msg);
}
return data;
}, err => {
const res = err.response;
const status = res.status;
const msg = res.data.msg;
switch (status) {
case 401:
case 402:
mv.$alert('请登录', {
type: 'error',
}).then(() => {
window.location.href = '';
});
break;
case 400:
case 500:
mv.$alert(msg, {
type: 'error',
});
break;
}
return Promise.reject(err);
});
export default http;
2.main.js入口文件
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import '@/style/init.styl';
import $http from '@/utils/http';
import EbrainTable from '@/components/EbrainTable';
import EbrainFrame from '@/components/EbrainFrame';
import EbrainTools from '@/components/EbrainTools';
import EbrainDialog from '@/components/EbrainDialog';
import EbrainSearch from '@/components/EbrainSearch';
import EbrainMain from '@/components/EbrainMain';
import EbrainBox from '@/components/EbrainBox';
import EbrainBoxTable from '@/components/EbrainBoxTable';
import EbrainUpload from '@/components/EbrainUpload';
import EbrainDialogTable from '@/components/EbrainDialogTable';
import EbrainDialogImport from '@/components/EbrainDialogImport';
import EbrainDialogExport from '@/components/EbrainDialogExport';
import Contextmenu from 'v-contextmenu';
import 'v-contextmenu/dist/index.css';
import '@/assets/font/iconfont.css';
Vue.use(ElementUI, { size: 'mini' });
Vue.use(Contextmenu);
Object.defineProperty(Vue.prototype, '$http', { value: $http });
Vue.component('EbrainTable', EbrainTable);
Vue.component('EbrainFrame', EbrainFrame);
Vue.component('EbrainTools', EbrainTools);
Vue.component('EbrainDialog', EbrainDialog);
Vue.component('EbrainSearch', EbrainSearch);
Vue.component('EbrainMain', EbrainMain);
Vue.component('EbrainBox', EbrainBox);
Vue.component('EbrainBoxTable', EbrainBoxTable);
Vue.component('EbrainUpload', EbrainUpload);
Vue.component('EbrainDialogTable', EbrainDialogTable);
Vue.component('EbrainDialogImport', EbrainDialogImport);
Vue.component('EbrainDialogExport', EbrainDialogExport);
Vue.config.productionTip = false;
export default new Vue({
router,
store,
render: h => h(App)
}).$mount('#app');
3.vuex配置文件
import Vue from 'vue';
import Vuex from 'vuex';
import _ from 'lodash';
import $http from '@/utils/http';
// import vm from '@/main';
Vue.use(Vuex);
const getTabs = () => {
let tabs = window.sessionStorage.getItem('tabs');
return (tabs && JSON.parse(tabs)) || [];
};
const state = {
menus: [],
isRouter: false,
menuCollapse: false,
permissions: [],
sysUser: {},
tabs: getTabs(),
dict: {},
pageObject: {},
};
const mutations = {
/**
* 设置state的方法,例:
* this.$store.commit('SET_STATE', {
* menus: menus
* })
* menus为需要设置的state
* @param state
* @param payload
*/
SET_STATE(state, payload) {
if (payload && typeof payload === 'object') {
_.forEach(payload, (v, k) => {
state[k] = v;
});
}
},
SET_TABS(state, payload) {
state.tabs = payload;
const tabs = JSON.stringify(payload);
window.sessionStorage.setItem('tabs', tabs);
},
SET_DICTIONARY(state, payload) {
if (payload) {
_.forEach(payload, (v, k) => {
state['dict'][k] = state['dict'][k] || {};
_.forEach(v, i => {
state['dict'][k][i.value] = i.label;
});
});
}
},
INI_STATE(state) {
state.menus = [];
state.permissions = [];
state.sysUser = [];
state.tabs = [];
state.isRouter = false;
window.sessionStorage.removeItem('access_token');
window.sessionStorage.removeItem('refresh_token');
window.sessionStorage.removeItem('tabs');
}
};
const getters = {
routes(state) {
const menus = state.menus;
const formatRoutes = (arr) => {
return arr.map(v => {
let { path, redirect, children, component, name, label, icon, keepAlive, id } = v;
const comp = () => {
const compPath = component === 'Layout' ? 'pages/layout/index' : component;
return import(`@/${compPath}.vue`);
};
redirect = redirect || '';
keepAlive = keepAlive === '0';
if (children && children.length) children = formatRoutes(children);
return {
path: path || '',
redirect,
children,
component: component ? comp : null,
name,
label,
icon,
meta: {
keepAlive,
menuId: id,
},
};
});
};
return formatRoutes(menus);
},
};
const actions = {
/**
* 获取菜单
*/
queryMenus({ commit }) {
return $http
.get('/admin/menu')
.then(({ data = [] }) => {
commit('SET_STATE', {
menus: data,
isRouter: true
});
});
},
queryUserInfo({ commit }) {
return $http
.get('/admin/user/info')
.then(({ data = {}}) => {
const { permissions = [], sysUser = {}} = data;
commit('SET_STATE', { permissions, sysUser });
});
},
signout({ commit }) {
return $http
.delete('/auth/token/logout')
.then(() => {
window.location.href = '';
// vm.$router.push('/login');
});
},
queryDict({ commit }, type) {
return $http
.get(`/admin/dict/type/${type}`)
.then(({ data = [] }) => {
commit('SET_DICTIONARY', {
[type]: data
});
});
},
};
export default new Vuex.Store({
state,
mutations,
getters,
actions,
});
4.路由配置
import Vue from 'vue';
import Router from 'vue-router';
import $store from '@/store';
Vue.use(Router);
const router = new Router({
routes: [{
path: '/',
redirect: '/login',
}, {
path: '/login',
name: 'login',
component: () => import('@/pages/login'),
}, {
path: '/qrCode',
name: 'qrCode',
component: () => import('@/pages/qrcode'),
}]
});
router.beforeEach(async (to, from, next) => {
const { fullPath, hash, meta, name, params, path } = to;
const isLogin = /\/login/.test(path);
const isQrCode = /\/qrCode/.test(path);
if (isLogin || isQrCode) {
next();
} else {
const { tabs, isRouter } = $store.state;
if (!isRouter) {
await $store.dispatch('queryMenus');
let { routes } = $store.getters;
router.addRoutes(routes);
next({ ...to, replace: true });
}
const hasTab = tabs.find(v => v.path === to.path);
if (!hasTab) {
to.meta.$keepAlive = false;
tabs.push({ fullPath, hash, meta, name, params, path });
$store.commit('SET_TABS', tabs);
} else {
to.meta.$keepAlive = true;
$store.commit('SET_TABS', tabs);
}
next();
}
});
export default router;
5.config配置文件
const path = require('path');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const url = 'http://192.168.1.110:9999';
module.exports = {
productionSourceMap: false,
devServer: {
/**
* 反向代理
*/
proxy: {
'/auth': {
target: url,
ws: true,
pathRewrite: {
'^/auth': '/auth'
}
},
'/admin': {
target: url,
ws: true,
pathRewrite: {
'^/admin': '/admin'
}
},
'/code': {
target: url,
ws: true,
pathRewrite: {
'^/code': '/code'
}
},
'/gen': {
target: url,
ws: true,
pathRewrite: {
'^/gen': '/gen'
}
},
'/daemon': {
target: url,
ws: true,
pathRewrite: {
'^/daemon': '/daemon'
}
},
'/tx': {
target: url,
ws: true,
pathRewrite: {
'^/tx': '/tx'
}
},
'/act': {
target: url,
ws: true,
pathRewrite: {
'^/act': '/act'
}
},
'/basicdata': {
target: url,
ws: true,
pathRewrite: {
'^/basicdata': '/basicdata'
}
},
'/devicemanager': {
target: url,
ws: true,
pathRewrite: {
'^/devicemanager': '/devicemanager'
}
},
'/productionplan': {
target: url,
ws: true,
pathRewrite: {
'^/productionplan': '/productionplan'
}
},
'/qc': {
target: url,
ws: true,
pathRewrite: {
'^/qc': '/qc'
}
},
'/purchase': {
target: url,
ws: true,
pathRewrite: {
'^/purchase': '/purchase'
}
},
'/productionexe': {
target: url,
ws: true,
pathRewrite: {
'^/productionexe': '/productionexe'
}
},
'/tallymanager': {
target: url,
ws: true,
pathRewrite: {
'^/tallymanager': '/tallymanager'
}
},
'/transportmanager': {
target: url,
ws: true,
pathRewrite: {
'^/transportmanager': '/transportmanager'
}
}
}
},
pluginOptions: {
/**
* stylus全局变量
*/
'style-resources-loader': {
preProcessor: 'stylus',
patterns: [
path.resolve(__dirname, './src/style/var.styl')
]
}
},
configureWebpack: {
plugins: [
/**
* gzip打包插件
*/
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /\.(js|css|svg)$/,
threshold: 8192,
minRatio: 0.8
})
]
}
};