vue-真实配置

194 阅读1分钟

1.app.vue

<template>
	<div id="app"
	     :class="{'openSidebar':isOpenSidebar,'hideSidebar':!isOpenSidebar}">
		<side-nav v-if="showNav"></side-nav>
		<div v-if="showNav"
		     class="app-header">
			<my-header></my-header>
		</div>
		<div class="top-bar"
		     v-if="showNav">
			<my-tabs></my-tabs>
			<nav-menu></nav-menu>
		</div>
		<div id="content"
		     class="content">
			<!-- <transition name="fade-transform"
			            mode="out-in"> -->
			<keep-alive :include="routePathArr"
			            :max="15">
				<router-view />
			</keep-alive>
			<!-- </transition> -->
		</div>
		<BottomBar v-if="showNav"></BottomBar>
	</div>
</template>

<script>
import fileList from '@/router/fileList';
import MyHeader from "@/components/mainUI/header/Header";
import NavMenu from "@/components/mainUI/NavMenu";
import SideNav from "@/components/mainUI/sideNav/SideNav";
import MyTabs from "@/components/mainUI/Tabs";
import BottomBar from "@/components/mainUI/BottomBar";
import { mapMutations, mapGetters } from "vuex";
export default {
	name: "App",
	data() {
		return {
			showNav: true,
			timer: null //计算屏幕宽高防抖,保存定时器对象
		};
	},
	methods: {
		...mapMutations(["SET_WINDOW_W", "SET_WINDOW_H"]),
		setContentHight() {
			if (this.timer) clearTimeout(this.timer);
			this.timer = setTimeout(() => {
				this.timer = null;
				if (this.showNav) {
					// 屏幕高度
					const windowH = document.documentElement.clientHeight || document.body.clientHeight;
					const windowW = document.documentElement.clientWidth || document.body.clientWidth;
					this.SET_WINDOW_W(windowW);
					this.SET_WINDOW_H(windowH);
					const headerH = $(".app-header").height();
					const topbarH = $(".top-bar").height();
					const bottomH = $(".bottom-bar").height();
					$("#content").height(windowH - headerH - topbarH - bottomH);
				} else {
					$("#content").height("100%");
				}
			}, 300);
		}
	},
	created() {
		if (this.userInfo.allMenuList.length !== 0) {
			this.userInfo.allMenuList.map((item) => {
				item.component = fileList[item.name];
				return item
			})
			this.$router.addRoutes(this.userInfo.allMenuList);
			this.$router.onReady(() => {
				this.$router.push(this.activeIndex);
			})
		}
	},
	mounted() {
		this.setContentHight();
		window.onresize = () => {
			this.setContentHight();
		}
	},
	computed: {
		...mapGetters(["userInfo", "isOpenSidebar", "routePathArr", "activeIndex"])
	},
	watch: {
		$route: {
			handler: function (val, oldVal) {
				if (val.meta.showNav === false) {
					this.showNav = false;
				} else {
					this.showNav = true;
				};
				this.setContentHight();
			}
		}
	},
	components: { MyHeader, NavMenu, SideNav, MyTabs, BottomBar }
};
</script>

<style scoped lang="stylus">
$maxWidth = 1440px
$padding = 30px
.app-header
	position relative
	z-index 2
.top-bar, .content
	box-sizing border-box
	transition padding-left 0.28s
.content
	padding-right $padding
	overflow hidden
	@media (max-width: $maxWidth)
		padding-right ($padding / 3)
.openSidebar
	.side-nav
		left 0
	.top-bar
		padding-left 200px
	.content
		padding-left 230px
.hideSidebar
	.side-nav
		left -200px
	.top-bar
		padding-left 0
	.content
		padding-left $padding
		@media (max-width: $maxWidth)
			padding-left ($padding / 3)
</style>

2.main.js

import 'element-ui/lib/theme-chalk/index.css';
import 'styles/index.styl'
import 'v-contextmenu/dist/index.css' //右键菜单相关样式
import 'highlight.js/styles/a11y-dark.css' //高亮代码相关样式

import Vue from 'vue'
import App from './App'
import router from './router'
import 'babel-polyfill'
import store from './store' //vuex存储文件
import ElementUI from 'element-ui';
import axios_ from './api/http' // axios封装
import Common from 'js/common' // 公共js
import contentmenu from 'v-contextmenu' //右键菜单组件
import 'js/directives.js' // 引入自定义指令
import rules from 'js/rules.js' // 引入自定义验证
import myConst from 'js/const.js' // 常量设置
import './vendor/core/scripts/core.js' //核心模块
// 设置全局混合模式
import setLayoutHeight from "@/assets/js/mixins/setLayoutHeight"; // 设置布局的高度
import components from './components/components.js'; //全局组件注册

Vue.prototype.axios = axios_; // 挂载到Vue实例上面
Vue.config.productionTip = false;

window.setLayoutHeight = setLayoutHeight
window.setLayoutHeight = setLayoutHeight

Vue.use(Common).use(ElementUI).use(contentmenu).use(rules).use(myConst).use(components);

/* eslint-disable no-new */
new Vue({
    el: '#app',
    router,
    store,
    components: {
        App
    },
    template: '<App/>'
})

3. vue-router

index.js

import Vue from 'vue'
import Router from 'vue-router'
import { getStore } from 'js/store'

// vue路由懒加载  异步加载
const Index = resolve => require(['@/pages/index/Index'], resolve)
const Login = resolve => require(['@/pages/login/Login'], resolve)
// const Register = resolve => require(['@/pages/register/Register'], resolve)
// 用户个人信息
const UserInfo = resolve => require(['@/pages/user/UserInfo'], resolve)
const CompanyInfo = resolve => require(['@/pages/user/CompanyInfo'], resolve)
// 新闻与通知
const News = resolve => require(['@/pages/system/news/News'], resolve)
const Notice = resolve => require(['@/pages/system/news/Notice'], resolve)
// 待办列表
const ToDoList = resolve => require(['@/pages/workflow/ToDoList'], resolve)
// 签约页面
const Sign = resolve => require(['@/pages/trade/sign/Sign'], resolve)

Vue.use(Router)

var router = new Router({
	routes: [
		{
			path: '*',
			redirect: '/index'
		},
		{
			path: '/',
			redirect: '/login'
		},
		{
			path: '/index',
			name: 'index',
			component: Index,
			meta: {
				title: '首页',
				requireAuth: true // 只要此字段为true,必须做鉴权处理
			}
		},
		{
			path: '/userInfo',
			name: 'userInfo',
			component: UserInfo,
			meta: {
				title: '个人信息',
				requireAuth: true
			}
        },
        {
			path: '/companyInfo',
			name: 'companyInfo',
			component: CompanyInfo,
			meta: {
				title: '企业信息',
				requireAuth: true
			}
		},
		{
			path: '/news',
			name: 'news',
			component: News,
			meta: {
				title: '新闻',
				requireAuth: true
			}
		},
		{
			path: '/notice',
			name: 'notice',
			component: Notice,
			meta: {
				title: '公告',
				requireAuth: true
			}
		},
		{
			path: '/login',
			name: 'login',
			component: Login,
			meta: {
				showNav: false // 不显示nav
			}
		},
		{
			path: '/sign',
			name: 'sign',
			component: Sign,
			meta: {
				showNav: false // 不显示nav
			}
		},
		{
			path: '/toDoList',
			name: 'toDoList',
			component: ToDoList,
			meta: {
				title: '我的待办',
				requireAuth: true
			}
		}

	]
})

let indexScrollTop = 0

router.beforeEach((to, from, next) => {
	// 路由进入下一个路由对象前,判断是否需要登陆
	// 在路由meta对象中由个requireAuth字段,只要此字段为true,必须做鉴权处理
	if (to.matched.some(res => res.meta.requireAuth)) {
		const token = getStore({ name: 'access_token', type: "string" });
		// 未登录
		if (!token) {
			next({
				path: '/login',
				query: {
					redirect: to.path // 将跳转的路由path作为参数,登录成功后再跳转到该路由
				}
			})
		} else {
			next()
			/* // 用户信息是否过期
			let overdueTime = token.overdueTime;
			let nowTime = +new Date();
			// 登陆过期和未过期
			if (nowTime > overdueTime) {
				// 登录过期的处理,君可按需处理之后再执行如下方法去登录页面
				// 我这里没有其他处理,直接去了登录页面
				next({
					path: '/login',
					query: {
						redirect: to.path
					}
				})
			} else {
				next()
			} */
		}
	} else {
		next()
	}
	if (to.path !== '/index') {
		// 记录现在滚动的位置
		indexScrollTop = document.body.scrollTop
	}
	// 修改网页title(暂时无意义)
	// document.title = to.meta.title || document.title
})
router.afterEach(route => {
	if (route.path !== '/index') {
		document.body.scrollTop = 0
	} else {
		Vue.nextTick(() => {
			// 回到之前滚动位置
			document.body.scrollTop = indexScrollTop
		})
	}
})
export default router

fileList

export default {
	// 系统管理
	class: resolve => require(['@/pages/system/manage/Class'], resolve),
	menu: resolve => require(['@/pages/system/manage/Menu'], resolve),
	organize: resolve => require(['@/pages/system/manage/Organize'], resolve),
	user: resolve => require(['@/pages/system/manage/User'], resolve),
	role: resolve => require(['@/pages/system/manage/Role'], resolve),

	// 系统维护
	data: resolve => require(['@/pages/system/config/Data'], resolve),
	log: resolve => require(['@/pages/system/config/Log'], resolve),
    config: resolve => require(['@/pages/system/config/Config'], resolve),
    exchangeRate: resolve => require(['@/pages/system/config/ExchangeRate'], resolve),
    hgTaxRate: resolve => require(['@/pages/system/config/HgTaxRate'], resolve),

	// 规则管理
	billRule: resolve => require(['@/pages/system/rule/BillRule'], resolve),
	entityRules: resolve => require(['@/pages/system/rule/EntityRules'], resolve),

	// 模板管理
	printTemplate: resolve => require(['@/pages/system/template/PrintTemplate'], resolve),
	rule: resolve => require(['@/pages/system/template/Rule'], resolve),
	message: resolve => require(['@/pages/system/template/Message'], resolve),
    voucherTemplate: resolve => require(['@/pages/system/template/VoucherTemplate'], resolve),
    signDataRule: resolve => require(['@/pages/system/template/SignDataRule'], resolve),

	// 控件定义
	selectConfig: resolve => require(['@/pages/system/controlConfig/SelectConfig'], resolve),
	btnConfig: resolve => require(['@/pages/system/controlConfig/BtnConfig'], resolve),
	tableConfig: resolve => require(['@/pages/system/controlConfig/TableConfig'], resolve),
	toolbarConfig: resolve => require(['@/pages/system/controlConfig/ToolbarConfig'], resolve),
	pageConfig: resolve => require(['@/pages/system/controlConfig/PageConfig'], resolve),

	// 业务建模
	nodeConfig: resolve => require(['@/pages/system/modeling/NodeConfig'], resolve),
	processConfig: resolve => require(['@/pages/system/modeling/ProcessConfig'], resolve),

	// AOP拦截
	AOP: resolve => require(['@/pages/system/AOP/AOP'], resolve),

	// 节假日
	holiday: resolve => require(['@/pages/system/holiday/Holiday'], resolve),
	// 新闻 公告
	newsManager: resolve => require(['@/pages/system/news/NewsManager'], resolve),
	noticeManager: resolve => require(['@/pages/system/news/NoticeManager'], resolve),

	// 租户管理
	purchase: resolve => require(['@/pages/tenant/Purchase'], resolve),
	purchaseRecord: resolve => require(['@/pages/tenant/PurchaseRecord'], resolve),
	trial: resolve => require(['@/pages/tenant/Trial'], resolve),
	appCenter: resolve => require(['@/pages/tenant/AppCenter'], resolve),
	bankInfo: resolve => require(['@/pages/tenant/BankInfo'], resolve),
	chargeStandard: resolve => require(['@/pages/tenant/ChargeStandard'], resolve),
	tenant: resolve => require(['@/pages/tenant/Tenant'], resolve),

	// 客户系统
	customer: resolve => require(['@/pages/customer/Customer'], resolve),
	suppliers: resolve => require(['@/pages/customer/Suppliers'], resolve),
	providers: resolve => require(['@/pages/customer/Providers'], resolve),
	hkCompany: resolve => require(['@/pages/customer/HkCompany'], resolve),
	distributors: resolve => require(['@/pages/customer/Distributors'], resolve),
	agreement: resolve => require(['@/pages/customer/Agreement'], resolve),
	settlement: resolve => require(['@/pages/customer/Settlement'], resolve),
	formula: resolve => require(['@/pages/customer/Formula'], resolve),

	// 商品管理
	commodity: resolve => require(['@/pages/commodity/Commodity'], resolve),
	hsCode: resolve => require(['@/pages/commodity/HSCode'], resolve),

	// 归类平台
	classify: resolve => require(['@/pages/classify/Classify'], resolve),

	// 贸易系统

	orderListInland: resolve => require(['@/pages/trade/orderList/OrderListInland'], resolve),
	orderListHk: resolve => require(['@/pages/trade/orderList/OrderListHk'], resolve),
	orderListImport: resolve => require(['@/pages/trade/orderList/OrderListImport'], resolve),
    orderListExport: resolve => require(['@/pages/trade/orderList/OrderListExport'], resolve),
    ordListBuy: resolve => require(['@/pages/trade/OrdListBuy'], resolve),
    ordListSale: resolve => require(['@/pages/trade/OrdListSale'], resolve),

	//财务系统
	acctReceipt: resolve => require(['@/pages/finance/AcctReceipt'], resolve),
	acctPay: resolve => require(['@/pages/finance/AcctPay'], resolve),
	acctPayEntry: resolve => require(['@/pages/finance/AcctPayEntry'], resolve),
	invoice: resolve => require(['@/pages/finance/Invoice'], resolve),
	pendingVerification: resolve => require(['@/pages/finance/PendingVerification'], resolve),
	verificationRecord: resolve => require(['@/pages/finance/VerificationRecord'], resolve),
	taxinvoice: resolve => require(['@/pages/finance/Taxinvoice'], resolve),
    exportTaxinvoice: resolve => require(['@/pages/finance/ExportTaxinvoice'], resolve),
    accountBank: resolve => require(['@/pages/finance/AccountBank'], resolve),
    voucher: resolve => require(['@/pages/finance/Voucher'], resolve),

	//关务
	declare: resolve => require(['@/pages/declare/Declare'], resolve),

	// 仓库系统
	intoWarehouse: resolve => require(['@/pages/storage/IntoWarehouse'], resolve),
	warehouse: resolve => require(['@/pages/storage/Warehouse'], resolve),
	outWarehouse: resolve => require(['@/pages/storage/OutWarehouse'], resolve),
	transportCompany: resolve => require(['@/pages/storage/TransportCompany'], resolve),
	logisticsCompany: resolve => require(['@/pages/storage/LogisticsCompany'], resolve),
	storeHouse: resolve => require(['@/pages/storage/StoreHouse'], resolve),

	// 物流系统
	deliver: resolve => require(['@/pages/transport/Deliver'], resolve),
	sendGoods: resolve => require(['@/pages/transport/SendGoods'], resolve),
    takeGoods: resolve => require(['@/pages/transport/TakeGoods'], resolve),

    // 标识系统
    signMangeList: resolve => require(['@/pages/sign/SignMangeList'], resolve),
    signSearch: resolve => require(['@/pages/sign/SignSearch'], resolve),

    // 融资管理
    finManageList: resolve => require(['@/pages/finManagement/FinManageList'], resolve)
}

3.vuex

index

import Vue from 'vue'
import Vuex from 'vuex'
import actions from './actions'
import * as getters from './getters'
import state from './state'
import mutations from './mutations'
//每次修改state都会在控制台打印log
import createLogger from 'vuex/dist/logger'

Vue.use(Vuex)

const debug = process.env.NODE_ENV === 'development'

export default new Vuex.Store({
	actions,
	getters,
	state,
	mutations,
	strict: debug, // 当debug=true时开启严格模式(性能有损耗)
	plugins: debug ? [createLogger()] : []
})

state.js

import {
	getStore
} from 'js/store'

const state = {
	news: localStorage.getItem('news'),
	// 主题颜色
	theme: getStore({
		name: 'theme'
	}) || '#1E56A0',
	// 保存页面选项卡数据
	options: getStore({
		name: 'options'
	}) || [{
		name: '首页',
		route: "/index"
	}],
	// 激活的页面index
	activeIndex: getStore({
		name: 'activeIndex'
	}) || '/index',
	// 用户信息
	userInfo: getStore({
		name: 'userInfo'
	}) || {
			allMenuList: [],
			leftMenu: [],
			mainMenu: {
				left: [],
				right: {}
			},
			permissions: []
		},
	// 窗口高度
	windowH: null,
	// 窗口宽度
	windowW: null,
	// 是显示侧边栏
	isOpenSidebar: false,
	// 域名相关
	domain: {
		prefix: "www.",
		suffix: ".ec-chain.com"
	},
	// 文件展示列表配置文件
	fileListTheaderData: [
		{
			type: 5,
			width: '',
			hasSort: false,
			isShow: true,
			prop: 'fileUrl',
			label: '文件名'
		},
		{
			type: 0,
			width: '',
			hasSort: false,
			isShow: true,
			prop: 'remark',
			label: '备注'
		},
		{
			type: 0,
			width: '',
			hasSort: false,
			isShow: true,
			prop: 'createUserName',
			label: '创建人'
		},
		{
			type: 8,
			width: '',
			hasSort: false,
			isShow: true,
			prop: 'createTime',
			label: '创建时间'
		}
	],
	// 组织结构数据
	orgTree: [],
	// 分类数据    1 页面  2 打印模板 3 实体验证  4 工具栏  5 表格  6 消息提醒  7 规则引擎
	classObj: {
		1: [],
		2: [],
		3: [],
		4: [],
		5: [],
		6: [],
		7: []
	}
}

export default state

getters

// 通常通过getters取数据 (this.$store.getters.news;)

export const news = state => state.news
export const theme = state => state.theme // 主题颜色

export const options = state => state.options
export const activeIndex = state => state.activeIndex
export const userInfo = state => state.userInfo
export const windowH = state => state.windowH
export const windowW = state => state.windowW
export const isOpenSidebar = state => state.isOpenSidebar
export const domain = state => state.domain
export const orgTree = state => state.orgTree
export const classObj = state => state.classObj
// 获得路由path数组
export const routePathArr = state => {
	return state.options.map((item) => {
		let text = item.route.replace('/', '');
		if (text.length !== 0) {
			text = text.substring(0, 1).toUpperCase() + text.substring(1);
		}
		return text
	})
}

mutations

import {
    setStore
} from 'js/store'

const mutations = {
    SET_NEWS(state, val) {
        state.news = val
    },
    // 主题颜色
    SET_THEME: (state, color) => {
        state.theme = color
        setStore({
            name: 'theme',
            content: state.theme
        })
    },
    // 添加tabs
    ADD_TABS(state, data) {
        state.options.push(data);
        setStore({
            name: 'options',
            content: state.options,
            type: 'Session'
        })
    },
    // 删除tabs
    DELETE_TABS(state, route) {
        let index = 0;
        for (let option of state.options) {
            if (option.route === route) {
                break;
            }
            index++;
        }
        state.options.splice(index, 1);
        setStore({
            name: 'options',
            content: state.options,
            type: 'Session'
        })
    },
    RESET_TABS(state) {
        state.options = [{
            name: '首页',
            route: "/index"
        }];
        setStore({
            name: 'options',
            content: state.options,
            type: 'Session'
        })
    },
    // 设置当前激活的tab
    SET_ACTIVE_INDEX(state, index) {
		state.activeIndex = index;
		setStore({
            name: 'activeIndex',
            content: state.activeIndex,
            type: 'Session'
        })
    },
    // 设置详情信息
    SET_USER_INFO(state, info) {
		state.userInfo = info;
		setStore({
            name: 'userInfo',
			content: info,
			type: "Session"
        })
	},
	 // 设置窗口高
	 SET_WINDOW_H(state, H) {
        state.windowH = H;
	},
	 // 设置窗口宽
	 SET_WINDOW_W(state, W) {
        state.windowW = W;
    },
	 // 设置边框开关
	 OPEN_SIDEBAR(state) {
        state.isOpenSidebar = !state.isOpenSidebar;
    },
	 // 设置组织树
	 SET_ORGTREE(state, tree) {
        state.orgTree = tree;
    },
	 // 设置分类
	SET_CLASS(state, [type, tree]) {
        state.classObj[type] = tree
    }
}

export default mutations

## actions
//异步处理

import Vue from 'vue'
const vm = new Vue({});

const actions = {
	GET_ORGTREE({ commit }) {
		vm.axios.get(`/api/common-service/orgs`, {
			pageNum: 1,
			pageSize: 999999999
		}).then((res) => {
			let data = res.data.records;
			data.sort((a, b) => {
				return a.orderNum - b.orderNum
			})
			const tree = vm.$treeFn.toTree(data, 0, {
				name: "orgName",
				pId: "parentId",
				pName: "pName",
				children: "children",
				originNode: "根节点"
			});
			commit('SET_ORGTREE', tree);
		});
	},
	GET_CLASS({ commit }, type) {
		return new Promise((resolve, reject) => {
			vm.axios.get(`/api/common-service/category/load-category/${type}`)
				.then((res) => {
					commit('SET_CLASS', [type, res.data.subCategory]);
					resolve(res);
				}).catch(() => {})
		})
	}
}

export default actions

4.config

index

'use strict'
// Template version: 1.3.1
// see http://vuejs-templates.github.io/webpack for documentation.

const path = require('path')

module.exports = {
    dev: {

        // Paths
        assetsSubDirectory: 'static',
        assetsPublicPath: '/',
        proxyTable: {
            '/api': {
                target: 'http://192.168.212.11:8080', // 10服务器端口
                // target: 'http://192.168.212.61:8080', // 61服务器端口
                changeOrigin: true, // 跨域
                pathRewrite: {
                    '^/api': '/'
                }
            }
        },

        // Various Dev Server settings
        host: "0.0.0.0", // can be overwritten by process.env.HOST
        port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined
        autoOpenBrowser: false,
        errorOverlay: true,
        notifyOnErrors: true,
        poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-

        /**
         * Source Maps
         */

        // https://webpack.js.org/configuration/devtool/#development
        devtool: 'cheap-module-eval-source-map',

        // If you have problems debugging vue-files in devtools,
        // set this to false - it *may* help
        // https://vue-loader.vuejs.org/en/options.html#cachebusting
        cacheBusting: true,

        cssSourceMap: true
    },

    build: {
        // Template for index.html
        index: path.resolve(__dirname, '../dist/index.html'),

        // Paths
        assetsRoot: path.resolve(__dirname, '../dist'),
        assetsSubDirectory: 'static',
        assetsPublicPath: './',

        /**
         * Source Maps
         */

        productionSourceMap: false,
        // https://webpack.js.org/configuration/devtool/#production
        devtool: '#source-map',

        // Gzip off by default as many popular static hosts such as
        // Surge or Netlify already gzip all static assets for you.
        // Before setting to `true`, make sure to:
        // npm install --save-dev compression-webpack-plugin
        productionGzip: false,
        productionGzipExtensions: ['js', 'css'],

        // Run the build command with an extra argument to
        // View the bundle analyzer report after build finishes:
        // `npm run build --report`
        // Set to `true` or `false` to always turn it on or off
        bundleAnalyzerReport: process.env.npm_config_report
    }
}

dev.env.js

'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"'
})

prod.env.js

'use strict'
module.exports = {
  NODE_ENV: `'${process.env.NODE_ENV}'`
}

5.axios

import Vue from 'vue'
import axios from 'axios'; // 引入axios
import QS from 'qs'; // 引入qs模块,用来序列化post类型的数据
import router from '../router'
import dev from './dev'
import { setStore, getStore, removeStore } from 'js/store'
import {
	showLoading,
	hideLoading
} from '../assets/js/loading';

const pending = {}
const CancelToken = axios.CancelToken
const removePending = (key, isRequest = false) => {
	if (pending[key] && isRequest) {
		pending[key]('取消重复请求')
	}
	delete pending[key]
}
const getRequestIdentify = (config, isReuest = false) => {
	let url = config.url
	if (isReuest) {
		url = config.baseURL + config.url.substring(1, config.url.length)
	}
	return config.method === 'get' ? encodeURIComponent(url + JSON.stringify(config.params)) : encodeURIComponent(config.url + JSON.stringify(config.data))
}

let [oldServer, newServer] = [null, null];
// 环境的切换(暂时改用本地代理跨域,以下代码暂时不启用)
if (process.env.NODE_ENV === 'development') {
	oldServer = dev.oldServer;
	newServer = dev.newServer;
	// 设置文件服务器名称,用于拼接图片url
	setStore(dev.fileIpService);
} else {
	oldServer = "/api";
	newServer = "";
	let url = "";
	switch (process.env.NODE_ENV) {
		case "debug":
			url = 'http://192.168.212.11:8080';
			break;
		case "test":
			// 根据用户登录的ip判断 zuul服务器端口
			if (location.host === "192.168.212.60:8066") {
				// 61 内网
				url = 'http://192.168.212.61:8080';
			} else {
				// 61 外网
				url = "http://219.134.185.254:8088";
			}
			break;
		case "production":
			url = 'http://api.ispek.cn:9091';
			break;
		default:
			break;
	}
	axios.defaults.baseURL = url;
	// 设置文件服务器名称,用于拼接图片url
	setStore({
		name: "fileIpService",
		content: {
			ip: url,
			file: "/file-service/file/resources/",
			loginValidator: "/oauth-service/kaptcha/render"
		}
	})
}

// 请求超时时间
// axios.defaults.timeout = 10000;

// post请求头
// axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

let windowLoadingcontrol = null;
let windowAjaxTime = {
	start: null,
	end: null
};
// 请求拦截器
axios.interceptors.request.use(config => {
	// 处理短时间内重复的请求
	let requestData = getRequestIdentify(config, true);
	removePending(requestData, true);
	config.cancelToken = new CancelToken((c) => {
		pending[requestData] = c
	});
	// 按规则重写请求路径
	if (oldServer !== null && newServer !== null) {
		if (Array.isArray(oldServer)) {
			oldServer.forEach((item, index) => {
				config.url = config.url.replace(item, newServer[index]);
			})
		} else {
			config.url = config.url.replace(oldServer, newServer);
		}
	};
	showLoading();
	// 给每次请求写入开始时间 方便后面计算结束时间
	windowAjaxTime.start = new Date().getTime();
	// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
	// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断
	const token = getStore({ name: 'access_token', type: "string" });
	if (token) {
		config.headers.Authorization = 'Bearer ' + token;
	}
	return config;
}, error => {
	hideLoading();
	return Promise.error(error);
})

// 响应拦截器
axios.interceptors.response.use(response => {
	clearTimeout(windowLoadingcontrol);
	windowLoadingcontrol = setTimeout(() => {
		hideLoading();
	}, 300);
	// console.log('响应拦截器', response);
	if (response.headers['content-type'].indexOf('application/octet-stream') !== -1) {
		return Promise.resolve(response);
	} else if (Number(response.status) === 200 && Number(response.data.statusCode) === 200) {
		windowAjaxTime.end = new Date().getTime();
		response.data.resTime = windowAjaxTime.end - windowAjaxTime.start;
		return Promise.resolve(response);
		// blob不拦截
		/* if (response.data.constructor === Blob) {
			return Promise.resolve(response);
		} */
	} else {
		Vue.prototype.$message.error(response.data.message)
		return Promise.reject(response);
	}
}, (error) => {
	hideLoading();
	// console.log(error.response);
	// 服务器状态码不是200的情况
	if (error.response.status) {
		switch (error.response.status) {
			// 登录过期则跳转登录页面,并携带当前页面的路径
			// 在登录成功后返回当前页面,这一步需要在登录页操作。
			case 401:
				removeStore({ name: 'access_token' });
				removeStore({ name: 'userInfo' });
				router.replace({
					path: '/login',
					query: {
						redirect: router.currentRoute.fullPath
					}
				});
				location.reload();
				break;

			default:
				break;
		}
	}

	Vue.prototype.$message.error(error.response.data.message || "服务出错了,请稍后再试")
	return Promise.reject(error)
})

/**
 * get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
function get(url, params) {
	// 以下是对含有数组的参数的处理方式,根据目前要求合理选择
	// QS.stringify({ids: [1, 2, 3]}, { indices: false })
	//形式: ids=1&ids=2&ids=3
	// QS.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘indices‘})
	//形式: ids[0]=1&ids1]=2&ids[2]=3
	// QS.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘brackets‘})
	//形式:ids[]=1&ids[]=2&ids[]=3
	// QS.stringify({ids: [1, 2, 3]}, {arrayFormat: ‘repeat‘})
	//形式: ids=1&ids=2&ids=3
	const dealObjectValue = (obj) => {
		let param = {};
		if (obj === null || obj === undefined || obj === "") return param;
		for (let key in obj) {
			if (Array.isArray(obj[key])) {
				const arr = obj[key].find((item) => {
					if (item !== null && item !== undefined && item !== "") return item
				})
				if (arr) {
					param[key] = obj[key];
					/* param[key] = obj[key].map((item) => {
						debugger
						if (item === null || item === "") {
							debugger
							item = "null"
						}
						return item
					}); */
				}
			} else if (obj[key] instanceof Object) {
				param[key] = dealObjectValue(obj[key]);
			} else if (obj[key] !== null && obj[key] !== undefined && obj[key] !== "") {
				param[key] = obj[key];
			}
		}
		return param;
	};
	const newParams = dealObjectValue(params);
	return new Promise((resolve, reject) => {
		axios.get(url, {
			params: newParams,
			paramsSerializer: function (params) {
				return QS.stringify(params, { arrayFormat: 'indices' })
			}
		})
			.then(res => {
				resolve(res.data);
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

/**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {Object/String} config [Object:post请求配置,一般情况下用于设置请求头headers,不传是按默认配置;String:"json"]
 */
function post(url, params, config) {
	return new Promise((resolve, reject) => {
		let parameters = params;
		if (!config) {
			parameters = url.indexOf('/core/') >= 0 ? params : QS.stringify(params);
		} else if (config === "json") {
			config = {
				headers: { 'Content-Type': 'application/json;charset=utf-8' }
			}
		}
		axios.post(url, parameters, config)
			.then(res => {
				resolve(res.data);
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

/**
 * put方法, 对应put请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {Object/String} config [Object:post请求配置,一般情况下用于设置请求头headers,不传是按默认配置;String:"json"]
 */
function put(url, params, config) {
	return new Promise((resolve, reject) => {
		let parameters = params;
		if (!config) {
			parameters = QS.stringify(params);
		}
		axios.put(url, parameters)
			.then(res => {
				resolve(res.data);
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

/**
 * del方法, 对应delete请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
function del(url, params) {
	return new Promise((resolve, reject) => {
		// 此类型参数传递为url传递方式
		axios.delete(url, { params: params })
			// 此类型参数传递为对象传递
			// axios.delete(url, { data: params })
			// axios.delete(url, QS.stringify({ data: params }))
			.then(res => {
				resolve(res.data);
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

/**
 * upload方法   文件上传
 * @param {Array} files [文件对象数组]
 * @param {String} url [接口url]  默认值 '/api/file-service/file/upload'
 * @param {String} paramName [文件参数命名] 默认值 'files'
 * @param {Object} otherParam [其余参数]
 */
function upload(files, url, paramName, otherParam) {
	url = url || '/api/file-service/file/upload';
	paramName = paramName || 'files';
	let param = new FormData(); //创建form对象
	if (Object.prototype.isPrototypeOf(otherParam) && Object.keys(otherParam).length !== 0) {
		for (const key in otherParam) {
			if (otherParam.hasOwnProperty(key)) {
				const element = otherParam[key];
				param.append(key, element);
			}
		}
	}
	files.map((item) => {
		param.append(paramName, item);//通过append向form对象添加数据
	})
	let config = {
		headers: { 'Content-Type': 'multipart/form-data' }
	};
	return new Promise((resolve, reject) => {
		axios.post(url, param, config)
			.then(res => {
				resolve(res.data);
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

/**
 * download方法
 * @param {String} type [请求的方式]
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 * @param {String} fileType [导出文件类型] 默认值 xls
 * @param {String} fileName [导出文件名称] 默认值 导出文件
 * @param {Boolean} isDownLoad [是否下载] 默认值 true
 */
function download(url, params, fileType, fileName, isDownLoad = true) {
	fileType = fileType || 'xls';
	fileName = fileName || '导出文件';
	let config = {
		params: params,
		headers: {
			'content-disposition': "attachment;filename=total." + fileType,
			'Content-Type': 'application/x-download;charset=utf-8'
		},
		responseType: 'blob'
	};
	return new Promise((resolve, reject) => {
		axios.get(url, config)
			.then(err => {
				if (!err) return;
				let url = window.URL.createObjectURL(err.data);
				resolve(url);
				if (!isDownLoad) return;
				let link = document.createElement('a');
				link.style.display = 'none';
				link.href = url;
				link.setAttribute('download', `${fileName}.${fileType}`);
				document.body.appendChild(link);
				link.click();
			})
			.catch(err => {
				reject(err.data)
			})
	});
}

export default {
	get,
	post,
	put,
	del,
	upload,
	download,
	all: axios.all,
	spread: axios.spread
}

6.html

<!DOCTYPE html>
<html>

<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1.0">
	<link href="https://cdn.bootcss.com/animate.css/3.7.0/animate.min.css" rel="stylesheet">
	<title>供应链金融SaaS平台</title>
	<link rel="icon" href="/static/image/web_icon.ico" type="image/x-icon" />
	<script src="/static/js/pdfjs/pdf.js" charset="utf-8"></script>
</head>

<body>
	<div id="app"></div>
	<!-- built files will be auto injected -->
</body>

</html>