axios在vue中的使用

Axios在Vue中的使用

1.Axios基础用法:

1.1.axios请求方法:

请求方式具体是由后端定义的,请求的接口都是请求到后端,再由后端对数据进行操作

  1. get请求:
    • 用于从后端获取数据
    • axios.get()只有两个参数
    • get方法在Vue中的两种写法:(下面的代码包含在vue的组件里)
      <script>
      import axios from 'axios'
      export default {
        name: 'axios2-2',
        created () {
          
          /*带有params参数(可以不带params参数)后在访问时对应的请求路径就是
          http://localhost:8080/static/data.json?id=12
          */
          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>
      
  2. post请求:(一般用于新建)
    • 用于向后端提交数据(包括表单提交以及文件上传<上传图片、json文件等等>)
    • axios.post()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。
    • 请求数据的格式有两种:
      • form-data:用于表单提交(图片上传、文件上传)
      • application/json:大多数情况下都用这个,对前后端比较友好
    • 在vue中的代码写法(两种)post:
       let data = {
            id: 12
       } //data代表要提交的数据
       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)
      })
      
  3. put请求:(一般用于更新)
    • 用于编辑/更新数据(将所有的数据全部推送到后端,再由后端将数据更新到数据库中)
    • axios.put()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。
    • 在vue中的代码写法put:
      axios.put('/put',data).then(res=>{
        console.log(res)
      })
      
      另一种方法同上同理
  4. patch请求:
    • 用于编辑/更新数据(只将修改的数据推送到后端)
    • axios.patch()方法有三个参数,第一个是路径,第二个是请求的数据,第三个是config。
    • 在vue中的代码写法patch:
      axios.patch('/patch',data).then(res=>{
        console.log(res)
      })
      
  5. delete请求:
    • 用于删除数据,调用的时候要与后端沟通清楚删除接口如何调用
    • axios.delete()只有两个参数,与get请求类似
    • 在vue中的代码写法delete:
       axios.delete('/delete',{
         params:{
           id:12
         }
       }).then(res=>{
         console.log(res)
       })
      
      
      //将params改为data,就不是在url中进行传输的了
      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.并发请求

并发请求:同时进行多个请求,并统一处理返回值

两个方法:

  1. axios.all():
    • 参数是一个数组,数组里面是一个一个axios请求
  2. Axis.spread():
    • 在axios.all()的多个请求完成后,把返回数据进行分割后再进行统一的处理
  3. 在vue中的写法:
    axios.all([
      axios.get('../static/data.json'),
      axios.get('../static/city.json')
    ]).then(
      //spread中参数的个数取决于all方法中有几个参数
      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 () {
    // eslint-disable-next-line no-unused-vars
    // create的参数是axios的配置信息
    let instance = axios.create({
      baseURL: 'http://localhost:8080',
      timeout: 1000 // 设置超时时长(1s),如果后端长时间没有返回数据,接口就会报超时。状态码:401
    })
    instance.get('../static/data.json').then(res => {
      console.log(res)
    })
  }
}
</script>
  • 上述代码就是axios实例的创建,instance就是实例(类比java类实例的创建)
  • 在项目很简单的时候可以不用创建实例,直接使用axios
2.2.axios实例的相关配置
2.2.1.axios常用参数

即axios.create()方法里的参数,也可以是axios.get()的config

  1. 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
  2. timeout:请求的超时时长,单位是ms,默认1000ms(即1s)。如果请求的数据量较大,后端的处理时间较长,一旦超过该时间,后端就会返回401,代表超时。
  3. url:请求的路径
    let instance = axios.create({
      baseURL: 'http://localhost:8080',
      url:'../static/data.json'  //请求路径
    })
    instance.get('../static/data.json').then(res => {
      console.log(res)
    })
    
  4. method:请求方法(get, post,put,patch,delete)
  5. headers:{} 设置请求头,可以在请求头里添加一些参数
    let instance = axios.create({
      baseURL: 'http://localhost:8080',
      headers:{
         token:'' //用token识别当前登陆人的身份信息,将token传给后端
      }
    })
    instance.get('../static/data.json').then(res => {
      console.log(res)
    })
    
  6. params:{} 将请求参数拼接在url上
  7. data:{} 将请求参数放在请求体里
2.2.2.axios配置的地方

优先级:请求配置>实例配置>全局配置

  1. axios全局配置:(一般就修改以下两个)
    axios.defaults.timeout=1000
    axios.defaults.baseURL='http://localhost:8080'
    
  2. axios实例配置
    let instance = axios.create()
    //创建完实例后进行修改
    instance.defaults.timeout=3000
    
  3. axios请求配置
    instance.get('/data.json',{
         timeout=5000
    })
    

3.拦截器

在请求或响应被处理前拦截它们,即在发起请求之前做处理以及后端响应之后做一些处理

  1. 请求拦截器
    export default {
      name: 'axios3-3',
      components: {
      },
      created () {
        axios.interceptors.request.use(
          config => {
            // 在发送请求前做些什么
            return config
          },err=>{
            //在请求错误的时候做些什么
            return Promise.reject(err)
          })
      }
    }
    
    请求错误是指发送请求没有成功到达后端
  2. 响应拦截器
    axios.interceptors.response.use(
       res => {
       // 请求成功对响应数据做处理
       return res
       },
       // axios.get().then(res=>{}),响应的数据会到这儿,可以对数据进行操作
       err=>{
         //响应错误做些什么
         return Promise.reject(err)
       })
    
    响应错误是指请求已经到后端,后端返回错误信息
  3. 取消拦截器(一般不用)
     let interceptors = axios.interceptors.request.use
        (config => {
          config.headers = {
            auth: true
          }
          return config
        })
        axios.interceptors.request.eject(interceptors)
    
  4. 实例
    在请求的时候显示弹窗,在响应后隐藏弹窗
        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 => {
        //请求错误处理 一般http状态码以4开头,常见:401超时 404not found
        $('modal').show()
        setTimeout(()=>{
          $('modal').hide()
        },2000)  //先展示错误,过2s将其隐藏
        return Promise.reject(err)
      })
    axios.interceptors.response.use(
      res => {
        return res
      },
      err => {
        //响应错误处理 一般http状态码以5开头,常见:500系统错误 502系统重启
        $('modal').show()
        setTimeout(()=>{
          $('modal').hide()
        },2000)  //先展示错误,过2s将其隐藏
        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.项目配置:
  1. vue组件库vant安装:
    • 网址:https://youzan.github.io/vant/#/zh-CN/
  2. 后端请求的接口服务的运行:
    • 将下载下来的接口服务放在项目文件夹下(本电脑路径:/Users/taozehua/Downloads/软工2/vue学习/axios学习/axios_node_api-master)
      • 接口文档存放的是接口说明
    • 用终端打开该文件夹,运行
      1. cnpm install 安装依赖
      2. 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:

  1. 在项目中新建一个service文件夹,在该文件夹下创建一个js文件,将接口文档中给出的url和method对应写入文件。最后再用export default CONTACT_API将创建的api对象导入出去,方便在别的地方引用。
    const CONTACT_API = {
      // 获取联系人列表
      getContactList: {
        method: 'get',
        url: '/contactList'
      },
      // 新建联系人 form-data
      newContactForm: {
        method: 'post',
        url: '/contact/new/form'
      },
      // 新建联系人 appilcation/json
      newContactJson: {
        method: 'post',
        url: '/contact/new/json'
      },
      // 编辑联系人
      editContact: {
        method: 'put',
        url: '/contact/edit'
      },
      // 删除联系人
      delContact: {
        method: 'delete',
        url: '/contact'
      }
    }
    // 将创建的api对象导入出去,方便引用
    export default CONTACT_API
    
    
  2. 对axios进行封装,完成请求格式和参数的统一。在service文件夹下创建http.js文件,用于对axios进行进一步封装
    // 对axios进行封装
    import axios from 'axios'
    import service from './contactApi'
    
    // 将service循环遍历输出不同的请求方法
    let instance = axios.create({
      baseURL: 'http://localhost:9000/api',
      timeout: 1000
    })
    
    // 包裹请求方法的容器
    const Http = {}
    
    for (let key in service) {
      // api中存放有url和method
      let api = service[key]
    
      // async function()的作用是避免进入回调地狱
      Http[key] = async function (
        params, // 请求参数get:url,put,post,patch(data),delete:url
        isFormData = false, // 标识是否是form-data请求
        config = {} // 配置参数
      ) {
        let res = null
        try {
          // res对应于
          // axios.get().then(res=>{
          //
          //   }).catch(err=>{
          //
          //   })中的res
          res = await axios.get('url')
        } catch (err) {
          // 捕捉错误
          // 对应于
          // axios.get().then(res=>{
          //   }).catch(err=>{
          //
          //   })中的catch部分err
          res = err
        }
      }
    }
    
    
    完成代码:
    // 对axios进行封装
    import axios from 'axios'
    import service from './contactApi'
    
    // 将service循环遍历输出不同的请求方法
    let instance = axios.create({
      baseURL: 'http://localhost:9000/api',
      timeout: 1000
    })
    
    // 包裹请求方法的容器
    const Http = {}
    
    // 请求格式/参数的统一
    for (let key in service) {
      // api中存放有url和method
      let api = service[key]
    
      // async function()的作用是避免进入回调地狱
      Http[key] = async function (
        params, // 请求参数get:url,put,post,patch(data),delete:url
        isFormData = false, // 标识是否是form-data请求
        config = {} // 配置参数
      ) {
        let newParams = {}
        
        // content-type是否是form-data的判断
        // 如果是form-data格式,要new一个FormData的对象
        if (params && isFormData) {
          newParams = new FormData()
          for (let i in params) {
            newParams.append(i, params[i])
          }
        }
        // 如果是application/json格式
        else {
          // 直接赋值即可
          newParams = params
        }
        // 不同请求的判断
        let response = {} // 请求的返回值
        if (api.method === 'put' || api.method === 'post' || api.method === 'patch') {
          // 这三种方法请求相同
          try {
            response = await instance
            //newParams就相当于data,只不过换了个格式
            await instance[api.method](api.url, newParams, config)
          } catch (err) {
            response = err
          }
        } else if (api.method === 'delete' || api.method === 'get') {
          // delete 和 get没有第二个参数
          config.params = newParams
          try {
            response = await instance
            await instance[api.method](api.url, config)
          } catch (err) {
            response = err
          }
        }
        return response
      }
    }
    
    
  3. 加上请求拦截器
    // 拦截器的添加
    
    // 请求拦截器
    instance.interceptors.request.use(config => {
      // 发起请求前做些什么
      // Toast.loading会在页面中出现等待的图标
      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
    
    
  4. 调用,在main.js中引入Http,全局都可以调用
    import Http from "../service/http"
    //把http挂在到vue实例上
    Vue.prototype.$Http=Http
    
  5. 验证
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值