Vue基础语法(二)

关于axios对数据的操作

 

由于我的笔记习惯性地写到注释里面,所以直接上代码吧.........

axios常用的五种请求方法:
<template>
  <div class="home"></div>
</template>

<script>
/*
    axios常用的五种请求方法:get,post,put,patch,delete
    get:获取数据  
    post:提交数据  表单提交文件上传
    put:更新数据  所有数据全部推送至服务端
    patch:更新数据  只将修改的数据推送到服务端(数据很多时)
    delete:删除数据
    具体的提交方式由后端定义
*/
import axios from 'axios'
export default {
  name: 'axios2-2',
  components: {},
  created() {
    //生命周期执行一个请求有一个接口用json文件代替,访问成功就是.then箭头函数输出当前请求
    //  http://localhost:8080/data.josn?id=12
    axios
      .get('/data.json', {
        params: {
          id: 12
        }
      })
      .then(res => {
        console.log(res)
      }),
      axios({
        method: 'get',
        url: '/data.json',
        params: {
          id: 12
        }
      }).then(res => {
        console.log(res)
      })
    //post
    //form-data  表单提交 比较老(图片文件上传)
    //applicition/json
    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请求
    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('/put', data).then(res => {
      console.log(res)
    })
    //patch请求
    axios.patch('/patch', data).then(res => {
      console.log(res)
    })
    //delete请求 只有两个参数
    axios
      .delete('/delete', {
        params: {
          id: 12
        }
      })
      .then(res => {
        console.log(res)
      })
    axios
      .delete('/delete', {
        data: {
          //??????没有Request Payload  ,原因自己去看官网文档 参考:http://www.axios-js.com/zh-cn/docs/#axios-delete-url-config-1
          id: 12
        }
      })
      .then(res => {
        console.log(res)
      })
    axios({
      method: 'delete',
      url: '/delete',
      params: {
        id: 12
      },
      data: {
        id: 12
      }
    }).then(res => {
      console.log(res)
    })
  }
}
</script>

 

处理并发请求 随便写两个.json来测试就好比如:

{
  "title": "axios in vue",
  "create-time": "2020-10"
}
<script>
//  并发请求:同时进行多个请求,并统一处理返回值
import axios from 'axios'
export default {
  name: 'axios2-3',
  created() {
    // axios.all() 参数是数组数组里的值是一个一个axios请求
    //axios.spread()作用是在axzios.all多个请求完成的时候把它的返回数据进行分隔处理然后对每一返回值进行统一处理
    axios.all([axios.get('/data.json'), axios.get('/city.json')]).then(
      axios.spread((dataRes, cityRes) => {
        console.log(dataRes, cityRes)
      })
    )
  }
}
</script>

 

axios实例与多个后端接口处理

<script>
// axios实例
//后端接口地址多个,并且超时时长不一样

import axios from 'axios'
export default {
  name: 'axios3-1',
  created() {
    let instance = axios.create({
      baseURL: 'http://localhost:8080',
      timeout: 1000 //超时时长就是在发起http请求的时候,如果服务端长时间没有返回数据接口就会报超时401,一般是后端定义
    })
    // eslint-disable-next-line no-unused-vars
    let axios2 = axios.create({
      baseURL: 'http://localhost:9090',
      timeout: 5000
    })
    instance.get('/data/json').then(res => {
      console.log(res)
    })
  }
}
</script>

 

axios配置参数有哪些

<script>
// axios基本的配置参数有哪些
import axios from 'axios'
export default {
  name: 'axios3-2',
  created() {
    axios.create({
      baseURL: 'http://localhost:8080', //请求的域名,基本地址  axios.get('/data.json')会把默认路径拼接在相对路径前面
      timeout: 1000, // 请求的超时时长单位一般是ms 超时返回401,超时会阻塞后端内容服务器带来很大压力需要及时释放资源
      url: '/data.json', //请求路径
      method: 'get,post,put,path,delete', //  请求方法
      headers: {
        token: ''
      }, // 请求头
      params: {}, // 会将请求参数拼接在url上
      data: {} // 请求参数放在请求体里
    })
    //以下优先级从低到高
    // 1.axios全局配置  defaults指向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
    })

    // 实际开发全局配置很少用
    //  有两种请求接口
    // http:localhost:9090
    // http:localhost:9091
    let instance2 = axios.create({
      baseURL: 'http:localhost:9090',
      timeout: 1000
    })
    let instance1 = axios.create({
      baseURL: 'http:localhost:9091',
      timeout: 3000
    })
    // baseURL,timeout,url,get,params
    instance2
      .get('/contactList', {
        params: {}
      })
      .then(res => {
        console.log(res)
      })
    // baseURL,timeout:5000,method,url
    instance1
      .get('/orderList', {
        timeout: 5000
      })
      .then(res => {
        console.log(res)
      })
  }
}
</script>

拦截器

<script>
//  拦截器:在请求或相应被处理前拦截他们
// 请求拦截器,相应拦截器
import axios from 'axios'
export default {
  name: 'axios3-3',
  created() {
    // 请求拦截器
    axios.interceptors.request.use(
      // use有两个参数 一个是请求前的回调函数 另一个是请求错误的回调函数
      config => {
        // 在发送请求前做些什么
        return config
      },
      err => {
        // 请求错误是做些什么
        return Promise.reject(err)
      }
    )
    //相应拦截器
    axios.interceptors.response.use(
      res => {
        // 请求成功对响应数据处理
        return res
      },
      err => {
        // 响应错误做些什么
        return Promise.reject(err)
      }
    )
    //axios.get().then(res=>{}).catch(err=>{})
    // 取消拦截器 了解
    let interceptors = axios.interceptors.request.use(config => {
      config.headers = {
        auth: true
      }
      return config
    })
    axios.interceptors.request.eject(interceptors) // 取消拦截

    //栗子  登录状态(token:'')
    let instance = axios.create({})
    instance.interceptors.request.use(config => {
      config.headers.token = ''
      return config
    })
    //访问不需要登录的接口
    let newInstance = axios.create({})

    // 移动端开发 请求成功隐藏弹窗
    let instance_wphone = axios.create({})
    instance_wphone.interceptors.request.use(config => {
      $('#modal').show()
      return config
    })
    instance_wphone.interceptors.request.use(res => {
      $('#modal').hide()
      return res
    })
  }
}
</script>

 

关于错误处理

<script>
// 错误处理: 请求错误时的处理
import axios from 'axios'
import { config } from 'vue/types/umd'
export default {
  name: 'axios3-4',

  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)
      }
    )
    axios
      .get('/data.json')
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.log(err)
      })
    // 栗子  :实际开发中一般添加统一错误处理
    let instance = axios.create({})
    instance.interceptors.request(
      config => {
        return config
      },
      err => {
        // 请求错误 一般http状态码以4开头,常见: 401超值, 404 not found
        $('modal').show()
        setTimeout(() => {
          $('#modal').hide()
        }, 2000)
        return err
      }
    )
    instance.interceptors.response.use(
      res => {
        return res
      },
      err => {
        // 响应错误处理 一般http状态码以5开头, 500 系统错误, 502,系统重启
        $('modal').show()
        setTimeout(() => {
          $('#modal').hide()
        }, 2000)
        return Promise.reject(err)
      }
    )
    instance
      .get('/data.json')
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.log(err)
      })
  }
}
</script>

 

取消正在进行的请求,比如加载的很慢不想等了,去进行下一个请求此时该请求作废

<script>
// 取消正在进行的http请求
import axios from 'axios'
export default {
  name: 'axios3-5',

  created() {
    let source = axios.CancelToken.source()
    axios
      .get('/data.json', {
        cancelToken: source.token
      })
      .then(res => {
        console.log(res)
      })
      .catch(err => {
        console.log(err)
      })

    // 取消请求(message可选)
    source.cancel('cancel http')

    // 什么时候可能用取消请求
    // 商城3~5s不想查了上一个请求取消
  }
}
</script>

 

一个小练习,联系人列表增删改查

引入了vant插件,这个不重要,喜欢用什么写都可以

封装前

<template>
  <div class="home">
    <!--联系人列表-->
    <van-contact-list :list="list" @add="onAdd" @edit="onEdit" />
    <!-- 联系人编辑 -->
    <van-popup style="height:100%" v-model:show="showEdit" position="bottom">
      <van-contact-edit
        :contact-info="editingContact"
        :is-edit="isEdit"
        @save="onSave"
        @delete="onDelete"
      />
    </van-popup>
  </div>
</template>

<script>
//import { createApp } from 'vue'
import { ContactList, Toast, ContactEdit, Popup } from 'vant'

// const app = createApp()

import axios from 'axios'
export default {
  name: 'ContactList',
  components: {
    [ContactList.name]: ContactList,
    //[Toast.name]: Toast,
    [ContactEdit.name]: ContactEdit,
    [Popup.name]: Popup
  },
  data() {
    return {
      // {
      //     id: 1,
      //     name: '',
      //     tel: ''
      //   }
      list: [],
      instance: null, //axios实例
      showEdit: false, //编辑弹窗的显隐
      editingContact: {}, //正在编辑的联系人数据
      isEdit: false //新建或编辑
    }
  },
  created() {
    this.instance = axios.create({
      baseURL: 'http://localhost:9000/api',
      timeout: 1000
    })
    this.getList()
  },
  methods: {
    //获取联系人列表
    getList() {
      this.instance
        .get('/contactList')
        .then(res => {
          this.list = res.data.data
        })
        .catch(err => {
          console.log(err)
          Toast('请求失败,请稍后再试')
        })
    },
    //添加联系人
    onAdd() {
      this.showEdit = true
      this.isEdit = false
    },
    //编辑联系人
    onEdit(info) {
      this.showEdit = true
      this.isEdit = true
      this.editingContact = info
    },
    //保存联系人
    onSave(info) {
      if (this.isEdit) {
        //编辑保存
        this.instance
          .put('/contact/edit', info)
          .then(res => {
            if (res.data.code === 200) {
              Toast('保存成功')
              this.showEdit = false
              this.getList()
            }
          })
          .catch(err => {
            console.log(err)
            Toast('请求失败,请稍后重试')
          })
      } else {
        //新建保存
        this.instance
          .post('/contact/new/json', info)
          .then(res => {
            if (res.data.code === 200) {
              Toast('保存成功')
              this.showEdit = false
              this.getList()
            }
          })
          .catch(err => {
            console.log(err)
            Toast('请求失败,请稍后重试')
          })
      }
    },
    //删除联系人
    onDelete(info) {
      this.instance
        .delete('/contact', {
          params: {
            id: info.id
          }
        })
        .then(res => {
          if (res.data.code === 200) {
            Toast('删除成功')
            this.showEdit = false
            this.getList()
          }
        })
        .catch(() => {
          Toast('请求失败,请稍后重试')
        })
    }
  }
}
</script>
<style scoped>
.van-contact-list_add {
  z-index: 0;
}
</style>

封装后

<template>
  <div class="home">
    <!--联系人列表-->
    <van-contact-list :list="list" @add="onAdd" @edit="onEdit" />
    <!-- 联系人编辑 -->
    <van-popup style="height:100%" v-model="showEdit" position="bottom">
      <van-contact-edit
        :contact-info="editingContact"
        :is-edit="isEdit"
        @save="onSave"
        @delete="onDelete"
      />
    </van-popup>
  </div>
</template>

<script>
//import { createApp } from 'vue'  , ContactList, Toast, ContactEdit, Popup
import { Button } from 'vant'
import { ContactList } from 'vant'
import { Toast } from 'vant'
import { ContactEdit } from 'vant'
import { Popup } from 'vant'

//import { ContactList, ContactEdit } from 'vant';

// const app = createApp()

import axios from 'axios'
export default {
  name: 'ContactList',
  components: {
    [Button.name]: Button,
    [ContactList.name]: ContactList,
    //[Toast.name]: Toast,
    [ContactEdit.name]: ContactEdit,
    [Popup.name]: Popup
  },
  data() {
    return {
      // {
      //     id: 1,
      //     name: '',
      //     tel: ''
      //   }
      list: [],
      instance: null, //axios实例
      showEdit: false, //编辑弹窗的显隐
      editingContact: {}, //正在编辑的联系人数据
      isEdit: false //新建或编辑
    }
  },
  created() {
    this.instance = axios.create({
      baseURL: 'http://localhost:9000/api',
      timeout: 1000
    })
    this.getList()
  },
  methods: {
    //获取联系人列表
    async getList() {
      let res = await this.$Http.getContactList()
      this.list = res.data
    },
    //添加联系人
    onAdd() {
      this.showEdit = true
      this.isEdit = false
    },
    //编辑联系人
    async onEdit(info) {
      this.showEdit = true
      this.isEdit = true
      this.editingContact = info
    },
    //保存联系人
    async onSave(info) {
      if (this.isEdit) {
        //编辑保存
        let res = await this.$Http.editContact(info)
        if (res.code === 200) {
          Toast('保存成功')
          this.showEdit = false
          this.getList()
        }
      } else {
        //新建保存
        let res = await this.$Http.newContactJson(info)
        if (res.code === 200) {
          Toast('保存成功')
          this.showEdit = false
          this.getList()
        }
      }
    },
    //删除联系人
    async onDelete(info) {
      let res = await this.$Http.delContact({
        id: info.id
      })
      if (res.code === 200) {
        Toast('删除成功')
        this.showEdit = false
        this.getList()
      }
      // this.instance
      //   .delete('/contact', {
      //     params: {
      //       id: info.id
      //     }
      //   })
      //   .then(res => {

      //   })
      //   .catch(() => {
      //     Toast('请求失败,请稍后重试')
      //   })
    }
  }
}
</script>
<style scoped>
.van-contact-list_add {
  z-index: 0;
}
</style>

contactApi.js

const CONTACT_API = {
  //获取联系人列表
  getContactList: {
    method: 'get',
    url: '/contactList'
  },
  //新建联系人 application/json
  newContactJson: {
    method: 'post',
    url: '/contact/new/json'
  },
  //编辑联系人
  editContact: {
    method: 'put',
    url: '/contact/edit'
  },
  //删除联系人
  delContact: {
    method: 'delete',
    url: '/contact'
  }
}
export default CONTACT_API

 

http,js

import axios from 'axios'
import service from './contactApi'
import { Toast } from 'vant'
// service 循环遍历输出不同的请求方法
let instance = axios.create({
  baseURL: 'http://localhost:9000/api',
  timeout: 1000
})
const Http = {} //包裹请求方法的容器
// 请求格式或参数的统一
for (let key in service) {
  let api = service[key] //url method
  // async 作用:避免进入回调地狱如一层一层箭头函数
  Http[key] = async function(
    params, // 请求参数  get:url,put,post,patch(data),delete:url
    isFormData = false, // 标识是否是form-data请求
    config = {} //配置参数
  ) {
    // let res = null
    // try{
    //     let res =  await axios.get('url')

    // }catch(err){
    //     res = err
    // }
    //let url = api.url
    let newParams = {}
    // content-type是否是form-data的判断
    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[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[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

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import axios from 'axios'

// import { createApp } from 'vue'
// import { Button } from 'vant'

// const app = createApp()
// app.use(Button)
import Http from './service/http'
Vue.prototype.$Http = Http
Vue.config.productionTip = false
Vue.prototype.$axios = axios
new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

完整的小练习,需要后台接口的私我,网上一位大神写好的.....

(ps:今天也是想ta的一天)

posted @ 2020-10-23 17:32  fiamme  阅读(321)  评论(0编辑  收藏  举报