Axios在Vue中的使用
1.Axios基础用法:
1.1.axios请求方法:
请求方式具体是由后端定义的,请求的接口都是请求到后端,再由后端对数据进行操作
-
get请求:
-
用于从后端获取数据 -
axios.get()只有两个参数 -
get方法在Vue中的两种写法:(下面的代码包含在vue的组件里) <script>
import axios from 'axios'
export default {
name: 'axios2-2',
created () {
axios.get('../static/data.json',{
params:{
id:12
}
}).then((res) => {
console.log(res)
})
axios({
method: 'get',
url: '../static/data.json',
params:{
id:12
}
}).then((res) => {
console.log(res)
})
}
}
</script>
-
post请求:(一般用于新建)
-
用于向后端提交数据(包括表单提交以及文件上传<上传图片、json文件等等>) -
axios.post()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。 -
请求数据的格式有两种:
- form-data:用于表单提交(图片上传、文件上传)
- application/json:大多数情况下都用这个,对前后端比较友好
-
在vue中的代码写法(两种)post: let data = {
id: 12
}
axios.post('/post', data).then(res => {
console.log(res)
})
axios({
method: 'post',
url: '/post',
data: data
}).then(res => {
console.log(res)
})
-
form-data格式的请求:(但请求的类型是application/json) let formData = new FormData()
for (let key in data) {
formData.append(key, data[key])
}
axios.post('/post', formData).then(res => {
console.log(res)
})
-
put请求:(一般用于更新)
-
用于编辑/更新数据(将所有的数据全部推送到后端,再由后端将数据更新到数据库中) -
axios.put()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。 -
在vue中的代码写法put: axios.put('/put',data).then(res=>{
console.log(res)
})
另一种方法同上同理 -
patch请求:
-
用于编辑/更新数据(只将修改的数据推送到后端) -
axios.patch()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。 -
在vue中的代码写法patch: axios.patch('/patch',data).then(res=>{
console.log(res)
})
-
delete请求:
-
用于删除数据,调用的时候要与后端沟通清楚删除接口如何调用 -
axios.delete()只有两个参数,与get请求类似 -
在vue中的代码写法delete: axios.delete('/delete',{
params:{
id:12
}
}).then(res=>{
console.log(res)
})
axios.delete('/delete', {
data: {
id: 12
}
}).then(res => {
console.log(res)
})
axios({
method: 'delete',
url: '/delete',
params: {},
data: {}
}).then(res => {
console.log(res)
})
1.2.并发请求
并发请求:同时进行多个请求,并统一处理返回值
两个方法:
-
axios.all():
-
Axis.spread():
- 在axios.all()的多个请求完成后,把返回数据进行分割后再进行统一的处理
-
在vue中的写法: axios.all([
axios.get('../static/data.json'),
axios.get('../static/city.json')
]).then(
axios.spread((dataRes, cityRes) => {
console.log(dataRes,cityRes)
})
)
2.axios方法深入:
2.1.创建axios实例
后端接口地址有多个,并且超时时长不一样。axios实例可以在实例中配置参数,用实例去请求,更加方便。
<script>
import axios from 'axios'
export default {
name: 'axios3-1',
components: {
},
created () {
let instance = axios.create({
baseURL: 'http://localhost:8080',
timeout: 1000
})
instance.get('../static/data.json').then(res => {
console.log(res)
})
}
}
</script>
2.2.axios实例的相关配置
2.2.1.axios常用参数
即axios.create()方法里的参数,也可以是axios.get()的config
-
baseURL:请求的域名/基本地址 let instance = axios.create({
baseURL: 'http://localhost:8080',
})
instance.get('../static/data.json').then(res => {
console.log(res)
})
baseURL的值和axios.get方法里的参数连接起来就是请求的路径:http://localhost:8080/static/data.json -
timeout:请求的超时时长,单位是ms,默认1000ms(即1s)。如果请求的数据量较大,后端的处理时间较长,一旦超过该时间,后端就会返回401,代表超时。 -
url:请求的路径 let instance = axios.create({
baseURL: 'http://localhost:8080',
url:'../static/data.json'
})
instance.get('../static/data.json').then(res => {
console.log(res)
})
-
method:请求方法(get, post,put,patch,delete) -
headers:{} 设置请求头,可以在请求头里添加一些参数 let instance = axios.create({
baseURL: 'http://localhost:8080',
headers:{
token:''
}
})
instance.get('../static/data.json').then(res => {
console.log(res)
})
-
params:{} 将请求参数拼接在url上 -
data:{} 将请求参数放在请求体里
2.2.2.axios配置的地方
优先级:请求配置>实例配置>全局配置
-
axios全局配置:(一般就修改以下两个) axios.defaults.timeout=1000
axios.defaults.baseURL='http://localhost:8080'
-
axios实例配置 let instance = axios.create()
instance.defaults.timeout=3000
-
axios请求配置 instance.get('/data.json',{
timeout=5000
})
3.拦截器
在请求或响应被处理前拦截它们,即在发起请求之前做处理以及后端响应之后做一些处理
-
请求拦截器 export default {
name: 'axios3-3',
components: {
},
created () {
axios.interceptors.request.use(
config => {
return config
},err=>{
return Promise.reject(err)
})
}
}
请求错误是指发送请求没有成功到达后端 -
响应拦截器 axios.interceptors.response.use(
res => {
return res
},
err=>{
return Promise.reject(err)
})
响应错误是指请求已经到后端,后端返回错误信息 -
取消拦截器(一般不用) let interceptors = axios.interceptors.request.use
(config => {
config.headers = {
auth: true
}
return config
})
axios.interceptors.request.eject(interceptors)
-
实例: 在请求的时候显示弹窗,在响应后隐藏弹窗 let instance = axios.create({})
instance.interceptors.request.use(config => {
$('modal').show()
return config
})
instance.interceptors.response.use(res => {
$('modal').hidden()
return res
})
4.错误处理
在请求错误时进行的处理
无论是请求错误还是响应错误,最后都会进入axios.get()的catch进行错误处理。在实际开发过程中,一般要添加统一的错误处理
import axios from 'axios'
export default {
name: 'axios3-4',
components: {
},
created () {
axios.interceptors.request.use(
config => {
return config
}, err => {
$('modal').show()
setTimeout(()=>{
$('modal').hide()
},2000)
return Promise.reject(err)
})
axios.interceptors.response.use(
res => {
return res
},
err => {
$('modal').show()
setTimeout(()=>{
$('modal').hide()
},2000)
return Promise.reject(err)
})
axios.get('../static/data.json').then(res => {
console.log(res)
}).catch(err=>{
console.log(err)
})
}
}
5.取消请求
取消正在进行的http请求(稍做了解,在实际项目中不多用)
let source = axios.CancelToken.source()
axios.get('../static/data.json', {
cancelToken: source.token
}).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
source.cancel('cancel http')
6.axios实战例子:
6.1.项目配置:
- vue组件库vant安装:
- 网址:https://youzan.github.io/vant/#/zh-CN/
- 后端请求的接口服务的运行:
- 将下载下来的接口服务放在项目文件夹下(本电脑路径:/Users/taozehua/Downloads/软工2/vue学习/axios学习/axios_node_api-master)
- 用终端打开该文件夹,运行
- cnpm install 安装依赖
- node index.js 启动后端服务
6.2.代码解析
<template>
<div class="home">
<!--从vant引入联系人列表-->
<van-contact-list
id="van-contact-list_add"
:list="list"
default-tag-text="默认"
@add="onAdd"
@edit="onEdit"
/>
// showEdit编辑弹窗的显示
<van-popup v-model="showEdit" position="bottom" id="van-popup">
<van-contact-edit
:contact-info="editingContact" // 正在编辑的联系人数据
:is-edit="isEdit" //是否在编辑,记录状态
@save="onSave"
@delete="onDelete"
/>
</van-popup>
</div>
</template>
<script>
//引入vant组件和axios
import {ContactList, Toast,ContactEdit, Popup} from 'vant'
import axios from 'axios'
export default {
name: 'contactList',
components: {
//注册要用到的vant组件,只有注册后才能显示在网页上
//Toast组件不需要注册,只有在template中用到的组件才要注册
[ContactList.name]: ContactList,
[ContactEdit.name]: ContactEdit
[Popup.name]: Popup
},
data () {
return {
list: [], // 联系人列表
instance: null, // axios实例
showEdit: false, // 编辑弹窗的显示
editingContact: {}, // 正在编辑的联系人数据
isEdit: false
}
},
methods: {
// 添加联系人
onAdd () {
this.showEdit = true
this.isEdit = false
},
// 编辑联系人
onEdit (info) {
this.showEdit = true
this.isEdit = true
this.editingContact = info //将内容添加到正在编辑的联系人的数据中
},
// 保存联系人
onSave () {
if (this.isEdit) {
// 编辑保存
// 接口文档里的/contact/edit有三个参数:id,name,tel
// 这三个参数不需要单独获取,已经存在了info中
// 编辑用put
this.instance.put('/contact/edit', info).then(
res => {
if (res.data.code === 200) {
Toast('编辑成功')
this.showEdit = false // 关闭弹窗
this.getList()
}
}).catch(() => {
Toast('编辑失败')
})
} else {
// 新建保存,将结果存到接口文档里的/contact/new/json中,用post向后端发送数据
this.instance.post('/contact/new/json', info).then(res => {
//检查返回的状态,200代表成功
if (res.data.code === 200) {
Toast('新建成功')
this.showEdit = false // 关闭弹窗
//新建后需要进行更新联系人列表,即重新获取联系人列表
this.getList()
}
}).catch(() => {
Toast('新建失败')
})
}
},
// 删除联系人
onDelete (info) {
this.instance.delete('/contact',{
//将id拼接在url上,查询接口文档,删除的参数只有id,且要将id拼接在url上
params:{
id:info.id
}
}).then(
res=>{
if (res.data.code === 200) {
Toast('删除成功')
this.showEdit = false // 删除成功后关闭弹窗
this.getList()
}
}).catch(() => {
Toast('删除失败')
})
},
//获取联系人列表
getList(){
//从后端获取数据,get参数对应的是接口文档里的url中的一个
this.instance.get('/contactList').then(res => {
//res是后端返回的数据,可以先使用consle.log(res)在浏览器中查看返回数据的格式
//再去取用数据
this.list = res.data.data
// eslint-disable-next-line handle-callback-err
}).catch(err => {
//使用vant的Toast轻提示组件输出错误信息
Toast('请求失败,请稍后重试')
})
}
},
created () {
//创建axios实例
this.instance = axios.create({
//baseURL对应接口文档里的后端接口地址
baseURL: 'http://localhost:9000/api',
timeout: 1000
})
//从后端获取联系人列表
this.getList()
}
}
</script>
<style scoped>
.van-contact-list_add{
z-index: 0;
}
<!--将弹窗铺满-->
.van-popup{
height: 100%;
}
</style>
7.axios进一步封装
将所有的url放在一个js文件中
代码见axios实例中的service文件夹
创建url统一的管理文件时,需要按照模块进行划分。eg:联系人列表、订单列表等不同的业务模块要封装到不同的js文件中
Eg:
- 在项目中新建一个service文件夹,在该文件夹下创建一个js文件,将接口文档中给出的url和method对应写入文件。最后再用export default CONTACT_API将创建的api对象导入出去,方便在别的地方引用。
const CONTACT_API = {
getContactList: {
method: 'get',
url: '/contactList'
},
newContactForm: {
method: 'post',
url: '/contact/new/form'
},
newContactJson: {
method: 'post',
url: '/contact/new/json'
},
editContact: {
method: 'put',
url: '/contact/edit'
},
delContact: {
method: 'delete',
url: '/contact'
}
}
export default CONTACT_API
-
对axios进行封装,完成请求格式和参数的统一。在service文件夹下创建http.js文件,用于对axios进行进一步封装
import axios from 'axios'
import service from './contactApi'
let instance = axios.create({
baseURL: 'http://localhost:9000/api',
timeout: 1000
})
const Http = {}
for (let key in service) {
let api = service[key]
Http[key] = async function (
params,
isFormData = false,
config = {}
) {
let res = null
try {
res = await axios.get('url')
} catch (err) {
res = err
}
}
}
完成代码:
import axios from 'axios'
import service from './contactApi'
let instance = axios.create({
baseURL: 'http://localhost:9000/api',
timeout: 1000
})
const Http = {}
for (let key in service) {
let api = service[key]
Http[key] = async function (
params,
isFormData = false,
config = {}
) {
let newParams = {}
if (params && isFormData) {
newParams = new FormData()
for (let i in params) {
newParams.append(i, params[i])
}
}
else {
newParams = params
}
let response = {}
if (api.method === 'put' || api.method === 'post' || api.method === 'patch') {
try {
response = await instance
await instance[api.method](api.url, newParams, config)
} catch (err) {
response = err
}
} else if (api.method === 'delete' || api.method === 'get') {
config.params = newParams
try {
response = await instance
await instance[api.method](api.url, config)
} catch (err) {
response = err
}
}
return response
}
}
-
加上请求拦截器
instance.interceptors.request.use(config => {
Toast.loading({
mask: false,
duration: 0,
forbidClick: true,
message: '加载中……'
})
return config
}, () => {
Toast.clear()
Toast('请求错误')
})
instance.interceptors.response.use(res => {
Toast.clear()
return res.data
}, () => {
Toast.clear()
Toast('请求错误')
})
export default Http
-
调用,在main.js中引入Http,全局都可以调用 import Http from "../service/http"
Vue.prototype.$Http=Http
-
验证
|