今天我们来写一个 vue的ajax插件。很多人会用axios,或者jquery,其实想想也没有必要,我们完全可以自己写一个这样插件,这样我对我们学习javascript还是很有帮助的。
一、兼容性问题
提到ajax我们可能会知道xhr 和xhr2,目前很多新的浏览器都支持了xhr2,但如果你想要兼容 ie9那麻烦,因为ie9不支持 xhr2;
xhr只支持字符串的传输,不支持二进制流文件,而且xhr2支持二进制流的上传,还有增加了丰富的api接口。
对于 xhr大家都很熟悉了,如果不懂可以点击xhr查看
那么xhr2增加了那些接口,我们来介绍一下
XHR2
XMLHttpRequest 简称 XHR
XMLHttpRequest level2 简称XHR2
XHR2在 XHR的基础上新增了很多接口
新增FormData对象 XMLHttpRequestUpload对象
属性
readyState 请求响应状态
status HTTP状态 404/200/503/403/304
responseText 响应内容
timeout 超时时间 xhr2
方法
abort()
open()
send()
XHR2没有新增方法
事件
readystatechagne
load 请求成功完成时触发 XHR2
progress 进度事件 下载重复触发大约50ms触发一次 XHR2
error 请求失败时触发 XHR2
loadstart 请求开始时触发 XHR2
loadend 请求结束时触发 无论成功都会触发 XHR2
abort 请求中断时触发 XHR2
timeout 请求超时时触发 XHR2
二、格式化数据
首先我们来看下看我们提交的数据结构
{
name:'useadmin',
pwd:'123456',
contents:[1,2,3,4],
id:{
id:10,
user:name
}
}
我们要怎样格式化这个json数据呢?如果是xhr1,我需要把数据格式化为
name:useadmin
pwd:123456
contents[0]:1
contents[1]:2
contents[2]:3
contents[3]:4
id[id]:10
id[user]:
admin_name:admin
admin_password:admin
//要把这个数组变一个字符串才能发送
name=useadmin&pwd=123456&contents[0]=1&contents[1]=2&contents[2]=3&contents[3]=4&id[id]=10&id[user]=&admin_name=admin&admin_password=admin就这样在把它串起来,其实就是跟url的参数一样
那么怎样我们才能把这个字符串变成一这样一个字符串呢?看下面代码
function argUrl(obj) { //将数据传进来
var result=[]; //将处理的数据以组件传过来
function argFormat(obj,name) {
if(typeof obj==="object"){ //判断是不是object,如个是遍历
for(let i in obj){
if(typeof obj[i]==="object"){//如果这字符串中还包含json或数组时
name?argFormat(obj[i],name+'['+i+']'):argFormat(obj[i],i); //判断字段名是否为空,空时把i传过去,不为空时把字段名传过去
}else{
if(name){ //encodeURIComponent转码,可以把+等不能识别的url参数转成unicode码
result.push(name+"["+i+"]"+'='+encodeURIComponent(obj[i]));
}else{
result.push(i+'='+encodeURIComponent(obj[i]));
}
}
}
return result.join('&'); //将数组转成字符串反回即可心生成上面的数据
}else{
result+=obj;
return result;
};
}
return argFormat(obj);调用处理
};
//这是xhr的参数的传递方式,注意,此方式不支持二进制流文件
xhr2处理这样的这符就比较容易了
function xhr2(obj) {
var past=new FormData(); //新建FormData对象,可以处理字符,二进制流文件
function argFormat(obj,name) {
if(typeof obj==="object"){
for(let i in obj){
if(typeof obj[i]==="object"){
if(obj[i].lastModified){//如果是二进流文,直接加入进去
name?past.append(name,obj[i]):past.append(i,obj[i]);
//past.append('字段名字',字段内容)
}else{
name?argFormat(obj[i],name+'['+i+']'):argFormat(obj[i],i);
}
}else{
if(name){
past.append(name+"["+i+"]",obj[i]);
}else{
past.append(i,obj[i])
}
}
}
return past;
}else{
return obj;
};
}
return argFormat(obj);
}
基本上与xhr的数据处理差不多,只是方式不一样,返回的是一个FormData对象
这里顺便介绍一下new Promise
function pro(){
return new Promise(function(resolve, reject) {
setTimeout(function(){
resolve(参数);
//失败时用 resolve(参数);
},3000)
})
}
//要接上面的返回的参数
//async是成对使用的,少了async,await就不能使用,大家注意的一下,基本上就是这样使用的
async getData(){
var data= await pro()//等待参数返回才会再向下执行
}
下面是整个ajax插件的代码,
export default function(Vue, opt) {
Vue.prototype.$ajax={
post:function (url, context) {
function argUrl(obj) {
var result=[];
function argFormat(obj,name) {
if(typeof obj==="object"){
for(let i in obj){
if(typeof obj[i]==="object"){
name?argFormat(obj[i],name+'['+i+']'):argFormat(obj[i],i);
}else{
if(name){
result.push(name+"["+i+"]"+'='+encodeURIComponent(obj[i]));
}else{
result.push(i+'='+encodeURIComponent(obj[i]));
}
}
}
return result.join('&');
}else{
result+=obj;
return result;
};
}
return argFormat(obj);
};
function xhr2(obj) {
var past=new FormData();
function argFormat(obj,name) {
if(typeof obj==="object"){
for(let i in obj){
if(typeof obj[i]==="object"){
if(obj[i].lastModified){
past.append(name,obj[i]);
}else{
name?argFormat(obj[i],name+'['+i+']'):argFormat(obj[i],i);
}
}else{
if(name){
past.append(name+"["+i+"]",obj[i]);
}else{
past.append(i,obj[i])
}
}
}
return past;
}else{
return obj;
};
}
return argFormat(obj);
}
return new Promise(function(resolve, reject) {
var xmlhttp = new XMLHttpRequest();
if(typeof FormData !== 'undefined'){//判断是否支持xhr2
var urldata=xhr2(context.data);
//这里具体查看你上面ajax内容
xmlhttp.timeout=context.timeout?context.timeout:10000;
xmlhttp.addEventListener('progress',function (e) {
context.progress?context.progress(e):'';
})
xmlhttp.addEventListener('load',function (e) {
context.load?context.load(e):'';
})
xmlhttp.addEventListener('error',function (e) {
context.error?context.error(e):'';
})
xmlhttp.addEventListener('loadstart',function (e) {
context.loadstart?context.loadstart(e):'';
})
xmlhttp.addEventListener('loadend',function (e) {
context.loadstart?context.loadstart(e):'';
})
}else{
var urldata=argUrl(context.data);
}
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
resolve(JSON.parse(xmlhttp.responseText));
}
};
xmlhttp.open("POST",url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
xmlhttp.setRequestHeader("Accept", "*/*");
// xmlhttp.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //设置请求头信息
xmlhttp.send(urldata);
})
}
}
}
使用
//引入
import Http from './common/http'
Vue.use(Http);
然后在你的组件下使用就可以了,
var data= await this.$ajax.post('http://192.168.26.86/3dplay/public/admin/login',{
data:this.sub,
load:function(e){
//事件
}
});
在根目录建了.babelrc文件,代码如下:
{
"presets": [
"es2015",
"stage-3"
],
"plugins": []
}
这个文件是用来将代码编译为es5要用到的,要想你的代码兼容ie9请查看Polyfill,这里就不陈述了,
代码放在:https://github.com/itvwork/vueteam
下一节我们将会使用koa node mongodb来搭建后环境,没接触过的小伙伴先去看一下资料
项目启动:
gulp
大家有什么建议可以发邮箱到我的E-mail,
我的QQ:1830305999
也可以加入我们的Q群:190949802
我的主页:www.itvwork.com网站还没建好,正在建设中
网友评论