背景
很多人在写前端代码的时候,都不做请求封装,这样容易出现的情况是,假设在一个项目中,有100个页面,每个页面都需要向服务器发送请求,来完成数据的交互,突然有一天,产品的哥们说,咱们得加个请求的验证,给请求交互的data里,加一个加密的数据,来保证数据的安全性,如果未进行封装的话,这100个页面中,每个请求都需要改一次,这就是个很庞大的工程,所以,我们在开始写代码的时候,对请求的封装,是一个很重要的设计
理解
所谓
操作
我们以Vue项目为例,使用vue-cli搭建项目,使axios来发送请求
文件结构如下
my-projext
|-node_modules
|-public
|-src
|-assets
|-components
|-router
|-store
|-views
|-App.vue
|-main.js
|-package.json
方法一:使用单独的文件来进行封装
首先,在src下新建一个文件夹api
并新建一个api.js
文件
my-projext
|-node_modules
|-public
|-src
+ |-api
+ |-api.js
|-assets
|-components
|-router
|-store
|-views
|-App.vue
|-main.js
|-package.json
api.js
添加如下内容
const apiUrl = 'https://www.yoursite.com/api/';
const axios = require('axios');
export function request(options = {}) {
axios[options.methods](
apiUrl+options.url,
options.data
).then(options.success)
.catch(options.fail)
}
经过这样的封装后,在页面中使用,就变成了
page中
import {request} from '@/api/api.js';
export default {
data(){
return {}
},
methdos:{
getData(){
request({
url:"getData",
data:{
param_1:'入参数据'
},
success:(res)=>{
console.log('成功回调')
}
})
}
}
}
也可以在main.js
中进行统一引入,然后注入到Vue.prototype
中,这样就不用单独页面进行单独引入了
//main.js
import {request} from '@/api/api.js';
Vue.prototype.$request = request;
//Page中使用
this.$request({
url:'xxxxxx'
})
这样的话,如果想在请求前增加请求拦截
,只需要在公共方法中,增加一个拦截即可
const apiUrl = 'https://www.yoursite.com/api/';
const axios = require('axios');
+ const userData = require('@/api/userData.js');//引入放置用户信息的公共文件
export function request(options = {}) {
+ options=beforeRequest(options)
axios[options.methods](
apiUrl+options.url,
options.data
- ).then(options.success)
+ ).then((res)=>{
+ res=beforeResponse(res)
+ options.success&&options.success(res)
+ })
.catch(options.fail)
}
+ export function beforeRequest(options = {}) {//请求前拦截的地方
+ options.header = options.header||{}
+ options.header.token = userData.token;
+ return options
+ }
+ export function beforeResponse(res = {}) {//收到相应后拦截的地方
+ if(res.header.status==200){
+ if(res.data.resCode==0){
+ //业务成功逻辑
+ }else{
+ //业务失败逻辑
+ }
+ return res.data;//例如,只将回调中的data交给业务,而在拦截器里统一处理状态
+ }else{
+ alert("网络错误")
+ return res
+ }
+ }
方法二:Vuex中进行封装
我们将请求及请求拦截器,单独放置在vuex中的一个module
里
my-projext
|-node_modules
|-public
|-src
- |-api
- |-api.js
|-store
+ |- modules
+ |-api.js
|- index.js
|-assets
|-components
|-router
|-views
|-App.vue
|-main.js
|-package.json
api.js
中的代码为
const axios = require('axios');
export default {
state: {
apiUrl:'https://www.yoursite.com/api/'
},
mutations: {
},
actions: {
request({state,commit,dispatch},options={}){//请求方法
this.dispatch('beforeRequest',options).then((options)=>{
axios[options.methods](
apiUrl+options.url,
options.data
).then((res)=>{
return Promise.resolve(res)
}).catch(options.fail)
}).then((res)=>{
return this.dispatch('beforeRequest',options)
})
},
beforeRequest({state,commit,dispatch},options={}){//请求前拦截
options.header = options.header||{}
options.header.token = this.state.userData.token;
return Promise.resolve(options)
},
beforeResponse({state,commit,dispatch},res = {}) {//收到相应后拦截的地方
if(res.header.status==200){
if(res.data.resCode==0){
//业务成功逻辑
}else{
//业务失败逻辑
}
return Promise.resolve(res.data);//例如,只将回调中的data交给业务,而在拦截器里统一处理状态
}else{
alert("网络错误")
return Promise.reject(res)
}
}
}
}
Page
中的代码为
import {request} from '@/api/api.js';
export default {
data(){
return {}
},
methdos:{
getData(){
this.$store.dispatch('request',{
url:"getData",
data:{
param_1:'入参数据'
},
success:
}).then((res)=>{
console.log('成功回调')
}).catch(()=>{
console.log('失败回调')
})
}
}
}
更多内容在 小寒大人的前端经验分享 更新