vuejs多环境配置
参考1:vue 不同环境的baseurl配置-环境变量 - 简书 (jianshu.com)
参考2:vue-cli3不同环境配置 - 简书 (jianshu.com)
实际前端开发时需要根据不同测试环境使用不同的配置,如dev、sit、uat、prod。
在package.json中的scripts
命令集里可以通过 --mode 来指定运行环境。
serve
命令不携带 --mode
时,默认运行环境为development
build
命令不携带 --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; } }); },