Vue

如何调用后台接口

后台接口使用指南

Posted by Ayi on September 23, 2018

前言

作为一名程序员,特别是一名前端程序员,你一定曾经存在过或者正在有这样的疑惑,每次后台说给个接口,我们用就是了,那我们到底是怎么用的呢。

以vue框架为例,在创建好项目以后,在src/api/Index.js的文件下先写入以下代码

import Vue from 'vue'
import axios from 'axios'
import VueJsonp from 'vue-jsonp'
Vue.use(VueJsonp)
// let baseUrl = '/api'
let vm = new Vue()

// 携带cookie信息
axios.defaults.withCredentials = true
// 设置全局的请求次数,请求的间隙
axios.defaults.retry = 4
axios.defaults.retryDelay = 1000

// 请求超时拦截,重新请求
axios.interceptors.response.use(undefined, function axiosRetryInterceptor (err) {
  var config = err.config
  // If config does not exist or the retry option is not set, reject
  if (!config || !config.retry) return Promise.reject(err)

  // Set the variable for keeping track of the retry count
  config.__retryCount = config.__retryCount || 0

  // Check if we've maxed out the total number of retries
  if (config.__retryCount >= config.retry) {
    // Reject with the error
    return Promise.reject(err)
  }

  // Increase the retry count
  config.__retryCount += 1

  // Create new promise to handle exponential backoff
  var backoff = new Promise(function (resolve) {
    setTimeout(function () {
      resolve()
    }, config.retryDelay || 1)
  })

  // Return the promise in which recalls axios to retry the request
  return backoff.then(function () {
    return axios(config)
  })
})

const CancelToken = axios.CancelToken

这时候,后台突然丢了一个地址过来说,这就是接口,让你调用,比如有一天泉总丢了这样的接口给我

http://172.16.121.99:8081/terminalGroup/findGroupList

定义接口

那么我要做的就是首先在上面的代码中定义自己的接口

const url = 'http://172.16.121.99:8081'

定义好了以后,加入get和post方法,并在定义的Api中加入自己的地址

let cancel

const Api = {
  url: url, // 自己定义的接口
  _doGetPromise (url, params, options) {
    let timeout = options && options.timeout ? options.timeout : 60000
    return new Promise((resolve, reject) => {
      axios.get(url, {
        timeout: timeout,
        params: params,
        cancelToken: new CancelToken(function executor (c) {
          cancel = c
        })
      }).then(response => {
        resolve(response.data)
      }).catch(response => {
        console.error('ajax error:', response)
        reject(response)
      })
    })
  },
  _doPostPromise (url, formData) {
    return new Promise((resolve, reject) => {
      axios.post(url, formData, {
        emulateJSON: false,
        emulateHTTP: false,
        cancelToken: new CancelToken(function executor (c) {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(res => {
        console.log('post error:', res)
        reject(res)
      })
    })
  },
  _doJsonpPromise (url, params) {
    return new Promise((resolve, reject) => {
      vm.$jsonp(url, params).then(res => {
        resolve(res)
      }).catch(response => {
        console.error('ajax error:', response)
        reject(response)
      })
    })
  }
	//自己定义的方法放在这
}

然后定义自己的方法,定义的位置就在刚才定义的API下面

定义的方法有两种,一种是需要传值给后台,一种是不需要

不需要传值给后台的写法

getfindGroupList () {
    return this._doGetPromise(url + '/terminalGroup/findGroupList', {
     
    })
  }

需要传值给后台的写法

getfindGroupTree (serviceId) {
    return this._doGetPromise(url + '/terminalGroup/findGroupTree', {
      serviceId: serviceId
    })
  }

最后在文件的末尾加上,这样才能让别的组件可以调用,其实就是分父子组件的写法

Vue.prototype.$cancelAjax = function (msg) {
  if (cancel) {
    cancel(msg || '手动中断请求')
  }
}
export default Api

接口文档的完整代码

import Vue from 'vue'
import axios from 'axios'
import VueJsonp from 'vue-jsonp'
Vue.use(VueJsonp)
// let baseUrl = '/api'
let vm = new Vue()

// 携带cookie信息
axios.defaults.withCredentials = true
// 设置全局的请求次数,请求的间隙
axios.defaults.retry = 4
axios.defaults.retryDelay = 1000

// 请求超时拦截,重新请求
axios.interceptors.response.use(undefined, function axiosRetryInterceptor (err) {
  var config = err.config
  // If config does not exist or the retry option is not set, reject
  if (!config || !config.retry) return Promise.reject(err)

  // Set the variable for keeping track of the retry count
  config.__retryCount = config.__retryCount || 0

  // Check if we've maxed out the total number of retries
  if (config.__retryCount >= config.retry) {
    // Reject with the error
    return Promise.reject(err)
  }

  // Increase the retry count
  config.__retryCount += 1

  // Create new promise to handle exponential backoff
  var backoff = new Promise(function (resolve) {
    setTimeout(function () {
      resolve()
    }, config.retryDelay || 1)
  })

  // Return the promise in which recalls axios to retry the request
  return backoff.then(function () {
    return axios(config)
  })
})

const CancelToken = axios.CancelToken
const baseUrl = 'http://api.map.baidu.com'
const url = 'http://172.16.121.99:8081'

let cancel

const Api = {
  baseUrl: baseUrl,
  url: url,
  _doGetPromise (url, params, options) {
    let timeout = options && options.timeout ? options.timeout : 60000
    return new Promise((resolve, reject) => {
      axios.get(url, {
        timeout: timeout,
        params: params,
        cancelToken: new CancelToken(function executor (c) {
          cancel = c
        })
      }).then(response => {
        resolve(response.data)
      }).catch(response => {
        console.error('ajax error:', response)
        reject(response)
      })
    })
  },
  _doPostPromise (url, formData) {
    return new Promise((resolve, reject) => {
      axios.post(url, formData, {
        emulateJSON: false,
        emulateHTTP: false,
        cancelToken: new CancelToken(function executor (c) {
          cancel = c
        })
      }).then(res => {
        resolve(res.data)
      }).catch(res => {
        console.log('post error:', res)
        reject(res)
      })
    })
  },
  _doJsonpPromise (url, params) {
    return new Promise((resolve, reject) => {
      vm.$jsonp(url, params).then(res => {
        resolve(res)
      }).catch(response => {
        console.error('ajax error:', response)
        reject(response)
      })
    })
  },

  /* --------------兴趣点查询------------ */
  // 兴趣点查询
  getLayerTree (query, region, output, ak) {
    return this._doJsonpPromise(baseUrl + '/place/v2/suggestion', {
      query: query,
      region: 'ALL',
      output: 'json',
      ak: 'dFS3zjvSFiCjYN8auETE2TvUxp6wfeBQ'
    })
  },
  // 添加设备下拉框
  getfindGroupList () {
    return this._doGetPromise(url + '/terminalGroup/findGroupList', {
     
    })
  },
  // 设备树获取
  getfindGroupTree (serviceId) {
    return this._doGetPromise(url + '/terminalGroup/findGroupTree', {
      serviceId: serviceId
    })
  }
}
// 切换页面强行中断请求 router.beforeEach中用到 
Vue.prototype.$cancelAjax = function (msg) {
  if (cancel) {
    cancel(msg || '手动中断请求')
  }
}
export default Api

在需要的组件中调用接口

在主要的组件中调用接口的时候,就像调用一个组件一样,需要将接口引进,但是不需要声明

import Api from '@/api/Index.js'

然后使用组件名.方法的方式调用接口,比如我需要将后台传回的数据用树展示的时候,直接从后台get数据就可以,在树组件里可以这样写

getfindGroupTree () {
      this.serviceId = 1
      Api.getfindGroupTree(this.serviceId)
        .then(data => {
          let datas = data.data
          console.log(datas)
          if (data.status === 0) {
            this.treeData = data.data
            console.log(this.treeData)
          } else {
            this.$message({
              type: 'warning',
              message: '获取数据失败'
            })
          }
        })
        .catch(res => {
          this.$message({
            type: 'error',
            message: '获取数据失败'
          })
        })
    }

其实这段代码的格式就是

getfindGroupTree () {
      Api.getfindGroupTree(this.serviceId)
        .then(data => {
          //接口成功调用后的操作
          } else {
            this.$message({
              type: 'warning',
              message: '获取数据失败'
            })
          }
        })
        .catch(res => {
          this.$message({
            type: 'error',
            message: '获取数据失败'
          })
        })
    }