有时候不想使用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 注册了全局都可以使用。
具体的代码可以看这里: https://github.com/YalongYan/vue-practice/tree/master/vue-native-ajax
vue实践系列请看这里: https://github.com/YalongYan/vue-practice
来源:https://www.cnblogs.com/yalong/p/10935567.html