用promise封装ajax_vue实践---vue结合 promise 封装原生ajax

有时候不想使用axios这样的外部依赖,想自己封装ajax,这里有两种方法

方法一,在单个页面内使用

封装的代码如下:

beforeCreate () {

this.$http = (() => {

let createFetch = (type, url, params) => {

return new Promise((resolve, reject) => {

let xhr = new XMLHttpRequest()

xhr.onreadystatechange = () => {

if (xhr.readyState === 4){

if(xhr.status === 200){

var res = xhr.responseText;

try {

res = JSON.parse(xhr.responseText)

} catch (e) {}

resolve(res)

} else {

reject(xhr.responseText)

}

}

}

url += url.includes('?') ? '&' : '?'

if (type === 'GET') {

let serialArr = []

Object.keys(params).forEach(v => {

serialArr.push(`${v}=${params[v]}`)

})

url += serialArr.join('&')

}

xhr.withCredentials = true; //支持跨域发送cookies

xhr.open(type, url, true);

xhr.send(type === 'GET' ? null : params);

})

}

return {

get: (...args) => createFetch("GET", args[0], args[1]),

post: (...args) => createFetch("POST", args[0], args[1])

}

})()

}

使用的代码如下:

this.$http.get('http://123.103.9.204:6058/official/rest/document/wenku/1/3293036/groupList', {pageSize: '1', pageSize: 30, groupType: 0}).then((res)=>{

if(res.flag == 0){

this.requestData = res.data

}

})

方法二,全局注册

封装的方法如下:

export default

{

install(Vue)

{

Vue.prototype.$http=function(options){

/*将数据转化为字符串*/

var strData=function(data){

var dataStr="";

for(var key in data){

dataStr += key+'='+data[key]+'&';

}

dataStr = dataStr && dataStr.slice(0,-1);

return dataStr;

};

/*创建 XMLHttpRequest 对象*/

var createXHR=function(){

var xhr;

if (window.XMLHttpRequest)

{// code for IE7+, Firefox, Chrome, Opera, Safari

xhr=new XMLHttpRequest();

}

else {// code for IE6, IE5

xhr=new ActiveXObject("Microsoft.XMLHTTP");

}

return xhr

};

/*向服务器发送请求*/

var open=function(xhr,type,url,async){

xhr.open(type,url,async);

};

var send=function(xhr,msg){

xhr.send(msg);

};

var setHeaders=function(xhr,headers){

xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");

if(!headers){

return false;

}

for(var key in headers){

xhr.setRequestHeader(key,headers[key]);

}

}

var request=function(xhr,opts){

if(opts.type==="GET"){

open(xhr,opts.type,opts.url+'?'+strData(opts.data),opts.async);

send(xhr,null);

}

else if(opts.type==="POST"){

open(xhr,opts.type,opts.url,opts.async);

if(opts.headers){

setHeaders(xhr,opts.headers);

}

send(xhr,strData(opts.data));

}

};

return new Promise((resolve,reject)=>{

if(!options || typeof options != 'object'){

reject(new Error("参数错误,请传入对象参数!"));

return false;

}

if(!options.url){

reject(new Error("url不能为空"));

return false;

}

options.type = options.type?options.type.toUpperCase():'GET';

options.async = (options.async && options.async === false)?false:true;

options.dataType = options.dataType || "json";

options.data = options.data || {};

options.headers = options.headers || {};

var dataStr=strData(options.data);

/*创建 XMLHttpRequest 对象*/

var xhr=createXHR();

/*创建服务器返回响应后执行操作函数*/

xhr.onreadystatechange=function(){

var responseData;

if(xhr.readyState == 4){

switch (xhr.status){

case 200:

switch (options.dataType){

case "xml":

responseData=xhr.responseXML;

break;

case "text":

responseData = xhr.responseText;

break;

case "json":

responseData = JSON.parse(xhr.responseText);

break;

}

resolve(responseData);

default:

reject(new Error("这里做错误处理"));

}

}

};

/*向服务器发送请求*/

request(xhr,options);

})

};

Vue.prototype.$post=function(options){

options.type='post';

return this.$http(options);

};

Vue.prototype.$get=function(options){

options.type='get';

return this.$http(options);

};

}

}

import Vue from 'vue'

import App from './App.vue'

import router from './router'

import Install from './install/index.js'

// 这里全局安装

Vue.use(Install)

new Vue({

el: '#app',

router,

render: h => h(App)

})

使用的代码如下:

var reuestData = {

url: "http://123.103.9.204:6058/official/rest/document/wenku/1/3293036/groupList",

data: {pageSize: '1', pageSize: 30, groupType: 0}

}

this.$get(reuestData).then((res)=>{

if(res.flag == 0) {

this.requestData = res.data

}

})

两种方法的比较:

方法一的每个页面要想使用, 都需要写相关的代码,而且由于使用了匿名函数立即执行,如果函数内部有错误,不好调试

方法二使用了全局注册,只要在main.js 注册了全局都可以使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值