|—providers
|-----util.js 工具函数
|-----api.js 接口地址
|-----axios.js 封装axios的文件
mkdir providers
touch util.js api.js axios.js
安装:
yarn add cross-env -D
在package.json里配置:
"scripts": {
"test":"cross-env scene=test webpack --config webpack.config.js",
"dev":"cross-env scene=dev webpack-dev-server --config webpack.config.js",
"build":"cross-env scene=prod webpack --config webpack.config.js"
},
在配置文件webpack.config.js通过内置插件DefinePlugin配置
var webpack = require('webpack');
plugins.push(new webpack.DefinePlugin({
'sceneParam': JSON.stringify(process.env.scene),
'laney':JSON.stringify('laney'),
'test':'"kkkkk"'
}));
重新启动就可以在项目中直接获取到 sceneParam 参数
参照:Element ui Form表单
https://element.eleme.cn/#/zh-CN/component/form
校验利用策略模式, 和es5里的form表单验证思想一致
校验成功后, 调取登陆接口
submitLogin(){
var {pass,username} = this.ruleForm
axios({
method:'post',
url:'http://localhost:8081/api/login',
data:{
name:username,
password:pass
}
}).then((res)=>{
if(res.data.statusCode==200) {
alert(res.data.data);
localStorage.setItem('token',res.data.token); //用户访问页面的钥匙
this.$router.push({
path:'/home'
});
} else {
alert(res.data.data);
}
});
}
pages/home.vue
export default {
data(){
return {
name:'laney',
params:this.$route.query,
infoData:{}
}
},
methods:{
getInfoList(){
var token = localStorage.getItem('token');
var test = {name:'laney',age:'20'}
var mn = Qs.stringify(test);
// this.$axios.post('http://localhost:8081/api/info',mn).then((res)=>{
// console.log('test kkkk-----------');
// })
this.$axios({
method:'post',
url:'http://localhost:8081/api/info',
data:mn,
headers:{
token:token
}
}).then((res)=>{
if(res.data.statusCode==200) {
this.infoData = res.data.result;
var tag = res.data.tag;
return this.$axios({
method:'post',
url:'http://localhost:8081/api/msg'
})
} else {
alert(res.data.result);
}
}).then((res)=>{
console.log(res.data.result)
});
}
},
mounted(){
this.getInfoList();
}
}
</script>
export default {
basic:{
login:'/api/login',
info:'/api/info',
msg:'/api/msg',
hello:'/api/hello'
}
}
import axios from './providers/axios.js';
import api from './providers/api.js';
//定义全局变量$axios
Vue.prototype.$axios = axios;
Vue.prototype.$api = api;
yarn add axios -D , 已安装的可以忽略
引入axios
import axios from 'axios';
导出的结构是:
export default {
post, //方法名
get,
pull
}
封装的目的:
1.需要把一些 api 的base路径配置好,以免多次重复写入
2.项目可能传递给接口的 数据 有json 和 formData 都需要考虑
3.对登陆后可能权限的 token需要获取 统一设置
4.对接口异常的情况需要统一处理
后面讲
整体思路是在传参的时候, 可以多加一个参数form(true,false), true代表需要formData , false或者不选代表json
参考: axios2.js
var typearr= {
'json':'application/json;charset=UTF-8',
'form':'application/x-www-form-urlencoded'
};
post (url, params) {
var isForm = params.form;
if(params.form) {
delete params.form;
}
if(isForm) {
params = Qs.stringify(params);
}
return new Promise((resolve,reject) => {
return axios.post(url,params, {
headers: {
'X-API-TOKEN':localStorage.getItem('token'),
'Content-Type': isForm ? typearr['form'] : typearr['json'],
'test':'ppp'
}
})
.then(response => {
if(response.status==200){
resolve(response.data);
}
//这里不需要异常提示了, 已经在拦截器设置
// else {
// Message({
// message: response.errorMsg,
// type: 'warning'
// });
// }
})
.catch(err => {
reject(err)
})
})
},
以news.vue为例
<script>
export default {
data(){
return {
infoData:{}
}
},
methods:{
getInfoList2(){
var res = this.$axios.post(this.$api.basic.info,{
kind:'school',
form:true
}).then((res)=>{
console.log(res);
});
},
getInfoList(){
this.$axios.post(this.$api.basic.info,{
kind:'school'
},'form').then((res)=>{
this.infoData = res.result;
if(res.tag==1){
return this.$axios.post(this.$api.basic.msg,{
tag:res.tag
})
}
}).then((res)=>{
if(res.kind==2){
return this.$axios.post(this.$api.basic.hello,{
id:res.kind
})
}
}).then((res)=>{
console.log(res.result);
})
}
},
mounted(){
this.getInfoList2();
// this.getInfoList();
}
}
</script>
var formData = new FormData();
formData.append('name','song');
formData.get('name');
//http request 拦截器 你给服务端 的数据
axios.interceptors.request.use(
config => {
config.headers.common = {
'X-API-TOKEN': localStorage.getItem('token'),
'version': '1.0',
'Content-Type': 'application/json;charset=UTF-8'
}
console.log('begin');
if (config.data.form) {
//转化成formData格式
// transformRequest只能用在 PUT, POST, PATCH 这几个请求方法
config.transformRequest=[function (data) {
//方式一
data.name='laney';
delete data.form;
var ret = '';
for (let it in data) {
ret += it+'=' +data[it] + '&';
}
return ret.substring(0,ret.length-1);
//方式二:
// var test2 = Qs.stringify(data);
// return test2;
}]
}
return config;
},
error => {
return Promise.reject(err);
}
);
//响应拦截器即异常处理 - -- 服务给我们的数据
axios.interceptors.response.use(response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
// return response
}, err => {
if (err && err.response) {
switch (err.response.status) {
case 400:
console.log('错误请求')
break;
case 401:
console.log('未授权,请重新登录')
break;
case 403:
console.log('拒绝访问')
break;
case 404:
console.log('请求错误,未找到该资源')
break;
case 405:
console.log('请求方法未允许')
break;
case 408:
console.log('请求超时')
break;
case 500:
console.log('服务器端出错')
break;
case 501:
console.log('网络未实现')
break;
case 502:
console.log('网络错误')
break;
case 503:
console.log('服务不可用')
break;
case 504:
console.log('网络超时')
break;
case 505:
console.log('http版本不支持该请求')
break;
default:
console.log(`连接错误${err.response.status}`)
}
} else {
console.log('连接到服务器失败')
}
return Promise.resolve(err.response)
})
然后开始封装函数
export default {
/**
* 封装post方法
* @param url
* @param data
* @returns {Promise}
*
*/
// 方式一: 包装一个 new Promise
// post (url, params) {
// return new Promise((resolve,reject) => {
// return axios.post(url,params)
// .then(response => {
// if(response.status==200){
// resolve(response.data);
// } else {
// alert(response.errorMsg);
// }
// })
// .catch(err => {
// reject(err)
// })
// })
// },
// 方式二: 包装一个 直接利用axios自身是一个Promise对象的思想封装
// post (url, params) {
// return axios.post(url,params)
// .then(response => {
// if(response.status==200){
// return Promise.resolve(response.data);
// //注意必须要有return,相当于new Promise里的resolve,告诉接口已经获取数据
// } else {
// alert(response.errorMsg);
// }
// })
// .catch(err => {
// reject(err)
// })
// },
//方式三
// 注意: axios在配置headers头的时候, 不要和上面的 拦截器重复配置
post (url, params) {
var isForm = params.form;
if(params.form) {
delete params.form;
}
if(isForm) {
params = Qs.stringify(params);
}
return axios({
method: 'post',
url:url,
data: params
}).then((response) => {
if(response.status==200){
return Promise.resolve(response.data)
} else {
<!-- 如果设置了拦截器, 这里不需要做异常处理 -->
alert(response.errorMsg);
}
},(e) => {
return Promise.reject(e)
})
// 或者catch捕获异常
.catch(function (error) {
})
},
//方式四:
// async post (url, params,contype) {
// if(contype=='form'){
// params = Qs.stringify(params);
// }
// var res = await axios({
// method: 'post',
// url:url,
// data: params
// });
// return res.data;
// },
get(url,params={}){
return new Promise((resolve,reject) => {
axios.get(url,{
params:params
})
.then(response => {
resolve(response.data);
})
.catch(err => {
reject(err)
})
})
},
}
在axios.js里 添加
import { Message} from 'element-ui';
然后直接使用
Message({
message: '提示信息',
type: 'warning'
});
// 使用数据拦截器
import axios from 'axios';
import Qs from 'qs';
import {
Message
} from 'element-ui';
axios.defaults.timeout = 5000;
// env_config
// dev 开发环境
// test 测试环境
// build 线上环境
var urlObj = {
dev: 'http://localhost:8081',
test: 'http://localhost:8081/',
build: 'https://www.17npw.net/api/'
}
console.log(urlObj[sceneParam]);
// Message('这是一条消息提示');
axios.defaults.baseURL = urlObj[sceneParam]; //填写域名
//http request 拦截器 客户端给服务端 的数据
axios.interceptors.request.use(
config => {
config.headers.common = {
'X-API-TOKEN': localStorage.getItem('token'),
'version': '1.0',
'Content-Type': 'application/json;charset=UTF-8'
}
console.log('begin');
if (config.data.form) {
//转化成formData格式
// transformRequest只能用在 PUT, POST, PATCH 这几个请求方法
config.transformRequest = [function (data) {
//方式一
delete data.form;
// var ret = '';
// for (let it in data) {
// ret += it+'=' +data[it] + '&';
// }
// return ret.substring(0,ret.length-1);
//方式二:
var test2 = Qs.stringify(data);
return test2;
}]
}
return config;
},
error => {
return Promise.reject(err);
}
);
//响应拦截器即异常处理 - -- 服务给客户端的数据进行处理
axios.interceptors.response.use(response => {
if (response.status === 200) {
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
// return response
}, err => {
if (err && err.response) {
var errorMsg = '';
switch (err.response.status) {
case 400:
console.log('错误请求')
errorMsg = '错误请求';
break;
case 401:
console.log('未授权,请重新登录');
errorMsg = '未授权,请重新登录';
break;
case 403:
console.log('拒绝访问')
errorMsg = '拒绝访问';
break;
case 404:
console.log('请求错误,未找到该资源')
errorMsg = '请求错误,未找到该资源';
break;
case 405:
console.log('请求方法未允许')
errorMsg = '请求方法未允许';
break;
case 408:
console.log('请求超时')
errorMsg = '请求超时';
break;
case 500:
console.log('服务器端出错')
errorMsg = '服务器端出错';
break;
case 501:
console.log('网络未实现')
errorMsg = '请求方法未允许';
break;
case 502:
console.log('网络错误')
errorMsg = '网络错误';
break;
case 503:
console.log('服务不可用')
errorMsg = '服务不可用';
break;
case 504:
console.log('网络超时')
errorMsg = '网络超时';
break;
case 505:
console.log('http版本不支持该请求')
errorMsg = 'http版本不支持该请求';
break;
default:
console.log(`连接错误${err.response.status}`)
}
Message({
message: errorMsg,
type: 'warning'
});
} else {
console.log('连接到服务器失败')
}
return Promise.resolve(err.response)
})
export default {
//post方法
// post(url,params){
// return new Promise((resolve,reject)=>{
// return axios.post(url,params)
// .then((response)=>{
// if(response.status==200){
// resolve(response.data);
// }
// })
// })
// },
// // 方式二: 包装一个 直接利用axios自身是一个Promise对象的思想封装
// post (url, params) {
// return axios.post(url,params)
// .then(response => {
// if(response.status==200){
// return Promise.resolve(response.data);
// //注意必须要有return,相当于new Promise里的resolve,告诉接口已经获取数据
// }
// })
// .catch(err => {
// reject(err)
// })
// },
// //方式三
// // 注意: axios在配置headers头的时候,会合并拦截器和函数封装里的headers的选项
// post (url, params) {
// return axios({
// method: 'post',
// url:url,
// data: params,
// headers:{
// 'X-API-TOKEN':localStorage.getItem('token'),
// 'Content-Type': isForm ? typearr['form'] : typearr['json'],
// 'test':'ppp'
// }
// }).then((response) => {
// if(response.status==200){
// return Promise.resolve(response.data)
// }
// },(e) => {
// return Promise.reject(e)
// })
// // 或者catch捕获异常
// .catch(function (error) {
// })
// },
//方式四:
async post(url, params) {
var res = await axios({
method: 'post',
url: url,
data: params
});
return res.data;
},
/**
* 封装patch请求
* @param url
* @param data
* @returns {Promise}
*/
patch(url, data = {}) {
return new Promise((resolve, reject) => {
axios.patch(url, data)
.then(response => {
resolve(response.data);
})
})
},
get(url, params = {}) {
return new Promise((resolve, reject) => {
axios.get(url, {
params: params
})
.then(response => {
resolve(response.data);
})
})
},
}