vuejs多环境配置
参考1:vue 不同环境的baseurl配置-环境变量 - 简书 (jianshu.com)
参考2:vue-cli3不同环境配置 - 简书 (jianshu.com)
实际前端开发时需要根据不同测试环境使用不同的配置,如dev、sit、uat、prod。

在package.json中的scripts命令集里可以通过 --mode 来指定运行环境。
serve命令不携带 --mode 时,默认运行环境为developmentbuild命令不携带 --mode 时,默认运行环境为production
具体操作如下:
1. 创建好vue项目后,在根目录创建各个环境的环境变量文件【.env.环境名】
需要注意的是
- 配置文件的后缀要与
package.json的scripts的--mode的值要相等 -
只有
NODE_ENV,BASE_URL 和以 VUE_APP_开头的变量才能通过 webpack.DefinePlugin 静态地嵌入到客户端侧的代码中。这是为了避免意外公开机器上可能具有相同名称的私钥。
.env.dev
NODE_ENV = 'development' VUE_APP_PORT = 8086 VUE_APP_SERVER_URL = 'http://x.x.x.x1:8081/' VUE_APP_SERVER_A_URL = 'http://x.x.x.x1:8082/' VUE_APP_SERVER_B_URL = 'http://x.x.x.x1:8083/'
.env.sit
NODE_ENV = 'sit' VUE_APP_PORT = 18086 VUE_APP_SERVER_URL = 'http://x.x.x.x2:8081/' VUE_APP_SERVER_A_URL = 'http://x.x.x.x2:8082/' VUE_APP_SERVER_B_URL = 'http://x.x.x.x2:8083/'
2. 在根目录创建vue.config.js配置文件
根据具体的项目要求添加配置,环境变量使用【process.env.变量名】
module.exports = {
// publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
devServer: {
host: '0.0.0.0',
port: process.env.VUE_APP_PORT,
https: false,
proxy: {
"/login": {
target: process.env.VUE_APP_SERVER_URL, //后台接口
ws: true, //如果要代理websockets
changeOrigin: true, //将选项changeOrigin设置true为基于名称的虚拟托管站点。
// hot: true,
pathRewrite: {
"^/login": ""
},
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: false, // 关闭debug
drop_console: true, // 关闭console
},
},
},
"/conf": {
target: process.env.VUE_APP_SERVER_A_URL, //后台接口
ws: true, //如果要代理websockets
changeOrigin: true, //将选项changeOrigin设置true为基于名称的虚拟托管站点。
// hot: true,
pathRewrite: {
"^/conf": ""
},
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: false, // 关闭debug
drop_console: true, // 关闭console
},
},
},
"/frs": {
target: process.env.VUE_APP_SERVER_B_URL, //frs接口 - 测试 stable
ws: true, //如果要代理websockets
changeOrigin: true, //将选项changeOrigin设置true为基于名称的虚拟托管站点。
// hot: true,
pathRewrite: {
"^/frs": ""
},
uglifyOptions: {
compress: {
warnings: false,
drop_debugger: false, // 关闭debug
drop_console: true, // 关闭console
},
},
},
},
overlay: {
warnings: false,
errors: false
},
}
};
3. 在package.json中添加运行命令,如下:

在项目根目录下运行对应的命令即可,如:【npm run sit】、【npm run dev】
样式设置
使用element-ui
安装命令:npm i element-ui -S
main.js
import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI)
注意:样式文件需要单独引入
路由设置
a. 使用vue-router3.+(vue2)
router/index.js
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router);
const router = new Router({
routes: [
{
path: '/',
name: '登录',
component: () => import('@/pages/login')
},
{
path: '/container',
name: '布局',
component: () => import('@/components/container'),
children: [
{
path: '/user',
name: '页面1',
component: () => import('@/pages/user'),
},
{
path: '/role',
name: '页面2',
component: () => import('@/pages/role'),
},
]
},
]
});
export default router;
main.js
import router from "./router";
new Vue({
router,
render: h => h(App),
}).$mount('#app')
b. 使用vue-router4.+(只能配合使用vue3以上版本)
router/index.js
import { createRouter, createWebHashHistory } from 'vue-router';
const router = new createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
name: '登录',
component: () => import('@/pages/login')
},
{
path: '/container',
name: '布局',
component: () => import('@/components/container'),
children: [
{
path: '/user',
name: '页面1',
component: () => import('@/pages/user'),
},
{
path: '/role',
name: '页面2',
component: () => import('@/pages/role'),
},
]
},
]
});
export default router;
接口设置
新建requester.js文件
import axios from 'axios';
import app from '@/main.js';
// 拦截重复请求
const CancelToken = axios.CancelToken
const whiteList = [] // 允许重复请求的API白名单
const cancelUrls = []; // 声明一个数组用于存储每个ajax请求的取消函数和ajax标识
// 判定器:取消被多次发起的请求,保留第一个
const cancelJudger = (config = {}, cancel) => {
let url = config.url.split('?')[0];
let i = cancelUrls.indexOf(url);
if (i > -1) {
if (typeof cancel === 'function') {
// 如果改地址已记录,取消当前操作
cancel();
} else {
// 如果改地址已记录,删除改记录
cancelUrls.splice(i, 1);
}
} else {
cancelUrls.push(url);
}
};
// 设置基础请求参数
let baseURL = "";
const request = axios.create({
baseURL,
timeout: 0
});
request.defaults.headers.post['Content-Type'] = 'application/json';
request.defaults.retry = 0;
request.defaults.retryDelay = 1000;
// // 加载进度设置
// let requestingCount = 0;
// const handleRequestLoading = () => {
// requestingCount++;
// if (requestingCount) {
// app.$store.commit('SHOW_LOADING');
// }
// };
// const handleResponseLoading = () => {
// requestingCount--;
// if (!requestingCount) {
// app.$store.commit('CLOSE_LOADING');
// }
// };
// 入参拦截器
request.interceptors.request.use(
// onFulfilled处理
request => {
console.log("[" + request.url + "]请求发起:" + JSON.stringify(request.data))
// 过滤重复请求
if (!whiteList.includes(request.url)) {
request.cancelToken = new CancelToken(c => {
cancelJudger(request, c);
});
}
// let storage = new Storage();
// let apiToken = storage.getItem('api-token');
// if(apiToken == '' ) {
// request.headers['api-token'] = '';
// } else {
// request.headers['api-token'] = apiToken;
// }
return request;
},
// onRejected处理
error => {
console.log(error.Message)
return Promise.reject(error);
}
);
// 出参拦截器
request.interceptors.response.use(
// onFulfilled处理
response => {
console.log("[" + response.config.url + "]请求响应:" + JSON.stringify(response.data))
cancelJudger(response.config)
return response;
},
// onRejected处理
error => {
if (axios.isCancel(error)) {
console.log(JSON.stringify(error))
app.$message.error("请勿频繁操作!");
} else {
console.log("[" + error.config.url + "]请求响应:" + JSON.stringify(error))
const config = error.config;
const status = error.response.status;
cancelJudger(config)
// 处理未通过验证的请求
if (status === 401) {
error.message = ": " + error.response.data.message;
app.$message.error("验证失败:" + error.message + " " + error.response.data.message);
window.open('/login', '_self');
return Promise.reject(error);
}
// 无需重试
if (!config || !config.retry) {
app.$message.error("操作异常" + error.message);
return Promise.reject(error);
}
// 需要重试
config.__retryCount = config.__retryCount || 0;
if (config.__retryCount >= config.retry) {
app.$message.error("操作异常" + error.message);
return Promise.reject(error);
}
config.__retryCount += 1;
const backoff = new Promise(resolve => {
setTimeout(() => {
app.$nextTick(() => {
resolve();
});
}, config.retryDelay || 1);
});
return backoff.then(() => {
return request(config);
});
}
return Promise.reject(error);
}
);
// 操作方法
export const requester = {
get: (url, params = {}, headers = {}, responseType) => {
return new Promise((resolve, reject) => {
request.get(url, {
params: params,
headers: headers,
responseType: responseType,
}).then(res => {
resolve(res.data);
}).catch(err => {
reject(err)
})
})
},
post: (url, params = {}, headers = {}) => {
return new Promise((resolve, reject) => {
request.post(url, params, { headers: headers })
.then(res => {
resolve(res.data);
}).catch(err => {
reject(err)
})
})
},
// 使用这种写法,err信息也会通过调用方的.then返回
post2: async (url, params = {}, headers = {}) => {
return await request.post(url, params, { headers: headers })
.then(res => {
return res.data;
}).catch(err => {
return err
})
},
put: (url, params = {}) => {
return new Promise((resolve, reject) => {
request.put(url, params)
.then(res => {
resolve(res.data);
}).catch(err => {
reject(err)
})
})
},
patch: (url, params = {}) => {
return new Promise((resolve, reject) => {
request.patch(url, params)
.then(res => {
resolve(res.data);
}).catch(err => {
reject(err)
})
})
},
del: (url, params = {}) => {
return new Promise((resolve, reject) => {
request.delete(url, params)
.then(res => {
resolve(res.data);
}).catch(err => {
reject(err)
})
})
},
}
在vue页面使用:
import { requester } from "../utils/requester.js";
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
let params = {
name: this.loginForm.account,
pwd: this.loginForm.password,
};
requester.post("/login/auth/login", params).then((res) => {
Message.info("submitForm1:" + JSON.stringify(res));
console.log("submitForm1:" + JSON.stringify(res))
});
} else {
return false;
}
});
},

浙公网安备 33010602011771号