Web前端最全vue中Axios的封装和API接口的管理,浅谈前端消息机制原理

Vue 编码基础

2.1.1. 组件规范

2.1.2. 模板中使用简单的表达式

2.1.3 指令都使用缩写形式

2.1.4 标签顺序保持一致

2.1.5 必须为 v-for 设置键值 key

2.1.6 v-show 与 v-if 选择

2.1.7 script 标签内部结构顺序

2.1.8 Vue Router 规范

Vue 项目目录规范

2.2.1 基础

2.2.2 使用 Vue-cli 脚手架

2.2.3 目录说明

2.2.4注释说明

2.2.5 其他

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

export default {

name: ‘Address’,

created () {

this.onLoad();

},

methods: {

// 获取数据

onLoad() {

// 调用api接口,并且提供了两个参数

apiAddress({

type: 0,

sort: 1

}).then(res => {

// 获取数据成功后的其他操作

………………

})

}

}

}

其他的api接口,就在pai.js中继续往下面扩展就可以了。友情提示,为每个接口写好注释哦!!!

api接口管理的一个好处就是,我们把api统一集中起来,如果后期需要修改接口,我们就直接在api.js中找到对应的修改就好了,而不用去每一个页面查找我们的接口然后再修改会很麻烦。关键是,万一修改的量比较大,就规格gg了。还有就是如果直接在我们的业务代码修改接口,一不小心还容易动到我们的业务代码造成不必要的麻烦。

好了,最后把完成的axios封装代码奉上。

/**axios封装

* 请求拦截、相应拦截、错误统一处理

*/

import axios from ‘axios’;import QS from ‘qs’;

import { Toast } from ‘vant’;

import store from ‘…/store/index’

// 环境的切换

if (process.env.NODE_ENV == ‘development’) {

axios.defaults.baseURL = ‘/api’;

} else if (process.env.NODE_ENV == ‘debug’) {

axios.defaults.baseURL = ‘’;

} else if (process.env.NODE_ENV == ‘production’) {

axios.defaults.baseURL = ‘http://api.123dailu.com/’;

}

// 请求超时时间

axios.defaults.timeout = 10000;

// post请求头

axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded;charset=UTF-8’;

// 请求拦截器

axios.interceptors.request.use(

config => {

// 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了

// 即使本地存在token,也有可能token是过期的,所以在响应拦截器中要对返回状态进行判断

const token = store.state.token;

token && (config.headers.Authorization = token);

return config;

},

error => {

return Promise.error(error);

})

// 响应拦截器

axios.interceptors.response.use(

response => {

if (response.status === 200) {

return Promise.resolve(response);

} else {

return Promise.reject(response);

}

},

// 服务器状态码不是200的情况

error => {

if (error.response.status) {

switch (error.response.status) {

// 401: 未登录

// 未登录则跳转登录页面,并携带当前页面的路径

// 在登录成功后返回当前页面,这一步需要在登录页操作。

case 401:

router.replace({

path: ‘/login’,

query: { redirect: router.currentRoute.fullPath }

});

break;

// 403 token过期

// 登录过期对用户进行提示

// 清除本地token和清空vuex中token对象

// 跳转登录页面

case 403:

Toast({

message: ‘登录过期,请重新登录’,

duration: 1000,

forbidClick: true

});

// 清除token

localStorage.removeItem(‘token’);

store.commit(‘loginSuccess’, null);

// 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面

setTimeout(() => {

router.replace({

path: ‘/login’,

query: {

redirect: router.currentRoute.fullPath

}

});

}, 1000);

break;

// 404请求不存在

case 404:

Toast({

message: ‘网络请求不存在’,

duration: 1500,

forbidClick: true

});

break;

// 其他错误,直接抛出错误提示

default:

Toast({

message: error.response.data.message,

duration: 1500,

forbidClick: true

});

}

return Promise.reject(error.response);

}

}

);

/**

* get方法,对应get请求

* @param {String} url [请求的url地址]

* @param {Object} params [请求时携带的参数]

*/

export function get(url, params){

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

axios.get(url, {

params: params

})

.then(res => {

resolve(res.data);

})

.catch(err => {

reject(err.data)

})

});

}

/**

* post方法,对应post请求

* @param {String} url [请求的url地址]

* @param {Object} params [请求时携带的参数]

*/

export function post(url, params) {

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

axios.post(url, QS.stringify(params))

.then(res => {

resolve(res.data);

})

.catch(err => {

reject(err.data)

})

});

}

如果喜欢,就给个❤❤吧(**)

*********华丽丽的分割线******************华丽丽的分割线******************华丽丽的分割线******************华丽丽的分割线******************华丽丽的分割线*********

2018.8.14更新


axios的封装根据需求的不同而不同。这里非常感谢评论里一些很中肯的建议,我也对此进行了思考和针对不同需求的改善。主要有以下改变:

1.优化axios封装,去掉之前的get和post

2.断网情况处理

3.更加模块化的api管理

4.接口域名有多个的情况

5.api挂载到vue.prototype上省去引入的步骤

http.js中axios封装的优化,先直接贴代码:

/**

* axios封装

* 请求拦截、响应拦截、错误统一处理

*/

import axios from ‘axios’;

import router from ‘…/router’;

import store from ‘…/store/index’;

import { Toast } from ‘vant’;

/**

* 提示函数

* 禁止点击蒙层、显示一秒后关闭

*/

const tip = msg => {

Toast({

message: msg,

duration: 1000,

forbidClick: true

});

}

/**

* 跳转登录页

* 携带当前页面路由,以期在登录页面完成登录后返回当前页面

*/

const toLogin = () => {

router.replace({

path: ‘/login’,

query: {

redirect: router.currentRoute.fullPath

}

});

}

/**

* 请求失败后的错误统一处理

* @param {Number} status 请求失败的状态码

*/

const errorHandle = (status, other) => {

// 状态码判断

switch (status) {

// 401: 未登录状态,跳转登录页

case 401:

toLogin();

break;

// 403 token过期

// 清除token并跳转登录页

case 403:

tip(‘登录过期,请重新登录’);

localStorage.removeItem(‘token’);

store.commit(‘loginSuccess’, null);

setTimeout(() => {

toLogin();

}, 1000);

break;

// 404请求不存在

case 404:

tip(‘请求的资源不存在’);

break;

default:

console.log(other);

}}

// 创建axios实例

var instance = axios.create({    timeout: 1000 * 12});

// 设置post请求头

instance.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’;

/**

* 请求拦截器

* 每次请求前,如果存在token则在请求头中携带token

*/

instance.interceptors.request.use(

config => {

// 登录流程控制中,根据本地是否存在token判断用户的登录情况

// 但是即使token存在,也有可能token是过期的,所以在每次的请求头中携带token

// 后台根据携带的token判断用户的登录情况,并返回给我们对应的状态码

// 而后我们可以在响应拦截器中,根据状态码进行一些统一的操作。

const token = store.state.token;

token && (config.headers.Authorization = token);

return config;

},

error => Promise.error(error))

// 响应拦截器

instance.interceptors.response.use(

// 请求成功

res => res.status === 200 ? Promise.resolve(res) : Promise.reject(res),

// 请求失败

error => {

const { response } = error;

if (response) {

// 请求已发出,但是不在2xx的范围

errorHandle(response.status, response.data.message);

return Promise.reject(response);

} else {

// 处理断网的情况

// eg:请求超时或断网时,更新state的network状态

// network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏

// 关于断网组件中的刷新重新获取数据,会在断网组件中说明

if (!window.navigator.onLine) {

store.commit(‘changeNetwork’, false);

} else {

return Promise.reject(error);

}

}

});

export default instance;

这个axios和之前的大同小异,做了如下几点改变:

1.去掉了之前get和post方法的封装,通过创建一个axios实例然后export default方法导出,这样使用起来更灵活一些。

2.去掉了通过环境变量控制baseUrl的值。考虑到接口会有多个不同域名的情况,所以准备通过js变量来控制接口域名。这点具体在api里会介绍。

3.增加了请求超时,即断网状态的处理。说下思路,当断网时,通过更新vuex中network的状态来控制断网提示组件的显示隐藏。断网提示一般会有重新加载数据的操作,这步会在后面对应的地方介绍。

4.公用函数进行抽出,简化代码,尽量保证单一职责原则。

下面说下api这块,考虑到一下需求:

1.更加模块化

2.更方便多人开发,有效减少解决命名冲突

3.处理接口域名有多个情况

这里这里呢新建了一个api文件夹,里面有一个index.js和一个base.js,以及多个根据模块划分的接口js文件。index.js是一个api的出口,base.js管理接口域名,其他js则用来管理各个模块的接口。

先放index.js代码:

/**

* api接口的统一出口

*/

// 文章模块接口

import article from ‘@/api/article’;

// 其他模块的接口……

// 导出接口

export default {

article,

// ……

}

index.js是一个api接口的出口,这样就可以把api接口根据功能划分为多个模块,利于多人协作开发,比如一个人只负责一个模块的开发等,还能方便每个模块中接口的命名哦。

base.js:

/**

* 接口域名的管理

*/

const base = {

sq: ‘https://xxxx111111.com/api/v1’,

bd: ‘http://xxxxx22222.com/api’

}

export default base;

通过base.js来管理我们的接口域名,不管有多少个都可以通过这里进行接口的定义。即使修改起来,也是很方便的。

最后就是接口模块的说明,例如上面的article.js:

/**

* article模块接口列表

*/

import base from ‘./base’; // 导入接口域名列表

import axios from ‘@/utils/http’; // 导入http中创建的axios实例

import qs from ‘qs’; // 根据需求是否导入qs模块

const article = {

// 新闻列表

articleList () {

return axios.get(${base.sq}/topics);

},

// 新闻详情,演示

articleDetail (id, params) {

return axios.get(${base.sq}/topic/${id}, {

params: params

});

},

// post提交

login (params) {

return axios.post(${base.sq}/accesstoken, qs.stringify(params));

}

// 其他接口…………

}

export default article;

1.通过直接引入我们封装好的axios实例,然后定义接口、调用axios实例并返回,可以更灵活的使用axios,比如你可以对post请求时提交的数据进行一个qs序列化的处理等。

2.请求的配置更灵活,你可以针对某个需求进行一个不同的配置。关于配置的优先级,axios文档说的很清楚,这个顺序是:在 lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。

3.restful风格的接口,也可以通过这种方式灵活的设置api接口地址。

最后,为了方便api的调用,我们需要将其挂载到vue的原型上。在main.js中:

import Vue from ‘vue’

import App from ‘./App’

import router from ‘./router’ // 导入路由文件

import store from ‘./store’ // 导入vuex文件

import api from ‘./api’ // 导入api接口

Vue.prototype.$api = api; // 将api挂载到vue的原型上

然后我们可以在页面中这样调用接口,eg:

methods: {

onLoad(id) {

this.$api.article.articleDetail(id, {

api: 123

}).then(res=> {

// 执行某些操作

})

}

}

再提一下断网的处理,这里只做一个简单的示例:

  
    
      

我没网了

                  

HTTP

  • HTTP 报文结构是怎样的?

  • HTTP有哪些请求方法?

  • GET 和 POST 有什么区别?

  • 如何理解 URI?

  • 如何理解 HTTP 状态码?

  • 简要概括一下 HTTP 的特点?HTTP 有哪些缺点?

  • 对 Accept 系列字段了解多少?

  • 对于定长和不定长的数据,HTTP 是怎么传输的?

  • HTTP 如何处理大文件的传输?

  • HTTP 中如何处理表单数据的提交?

  • HTTP1.1 如何解决 HTTP 的队头阻塞问题?

  • 对 Cookie 了解多少?

  • 如何理解 HTTP 代理?

  • 如何理解 HTTP 缓存及缓存代理?

  • 为什么产生代理缓存?

  • 源服务器的缓存控制

  • 客户端的缓存控制

  • 什么是跨域?浏览器如何拦截响应?如何解决?

    开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 15
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值