Axios的封装

封装要求

  • axios配置跨域
  • axios 请求拦截 可访问 vuex ,跳转路由
  • 封装要求 api集中管理
  • api多文件管理,自动挂载(便于协同开发)

创建好项目后 nuxt里面已经内置了axios 无需下载 只需在 nuxt.config.js 开启即可
ps: 我创建的nuxt版本为 "nuxt": "^2.15.7"

---- nuxt.config.js -----

export default {
	modules: [
    	'@nuxtjs/axios',
    	 // 是否开启跨域代理配置 根据项目酌情选择
    	'@nuxtjs/proxy'
	],
	axios: {
		// 开启允许跨域 根据项目酌情选择
    	proxy: true
  	},
  	// 跨域配置 此处配置需酌情改变
	proxy: {
	    '/api': {
	      changeOrigin: true,
	      target: 'http://XXX.XXX.X.X', // 允许跨域的服务器地址
	      pathRewrite: {
	        '^/api': ''
	      }
	    }
	  },
}
...

到此为止 已经成功的引入进来 axios
接下来封装axios 并增加 拦截

plugins 目录下新建文件夹 axios.js

import Vue from 'vue'

export default ({ app, $axios, store, redirect }, inject) => {
  $axios.defaults.baseURL = '项目地址'
  $axios.defaults.timeout = 5000

  // 请求拦截
  $axios.onRequest((config) => {
  	// 本项目token 存储在vuex里面 
    const token = store.state.user.token
    if (token) config.headers.token= token
  })

  // 服务器返回异常拦截
  $axios.onError((error) => {
    return error
  })

  // 接口数据返回拦截
  $axios.onResponse((response) => {
  	// 状态码异常 跳转到登陆
	// redirect('/login')
      return response
  })
}

完成了对axios的一些基本封装后 接下来 集中管理api
首先在 nuxt.config.js 的同级目录下创建名称为 api 的文件夹
这个文件里面存放所有的api接口
在创建好的文件夹下面 新建 index.js

---- index.js ----
// api模块化自动加载
/**
*** 这里要注意 下面代码匹配的文件,是名称内包含 Api.js 的文件
*** 意味着要想自动加载 api 其他文件的名称 必须以Api.js 结尾
***	例如 loginApi.js  或者 userApi.js
***	如果不想以Api.js 结尾来命名 
*** 需要修改 正则表达式为
*** const files = require.context('./', true, /\.js$/)
*** 并且在循环里面判断如果是index.js 就return 
*** 也就是剔除index.js
*** 博主这里用的是以Api.js 结尾来命名文件的方式
**/
const files = require.context('./', true, /\Api.js$/)
// eslint-disable-next-line import/no-mutable-exports
let apiEntire = {}
files.keys().forEach((key) => {
  const tmp = files(key).default
  apiEntire = { ...apiEntire, ...tmp }
})

export default apiEntire

到这里api的就可以集中加载
假如业务逻辑需要 登陆用户中心
我们只需要在 index.js 这里创建同级的目录
但是目录名字必须要以 Api.js 结尾来命名
创建 loginApi.js

`参数不在这里传哦`

---- loginApi.js ----
// api集中管理 
 // 获取手机验证码
  getSmsCode: {
    url: `mobile/`,
    method: 'get',
    header:{
    	from:'4'
	}
  },

  // 手机号检验
  mobileCheck: {
    url: '/mobileCheck',
    method: 'get'
  },

这个时候 api已经集中管理
准备引入 axios
/ plugins / axios.js 里面增加以下代码
ps: 底部有完整代码

// 导入暴漏出来的api
import apiEntire from '@/api'

export default ({ app, $axios, store, redirect }, inject) => {
......
const API = {}
  for (const i in apiEntire) {
  	// 调用api时候的参数 
  	// 第一位为 post参数 第二位为get参数
    API[i] = function(data = '', params = '') {
      const { url, method, headers } = { ...apiEntire[i] }
      return $axios({
        url,
        method,
        headers,
        data,
        params
      })
    }
  }
  app.api = API
  inject('api', API)
......
}

axios 完整代码

import Vue from 'vue'
import apiEntire from '@/api'

export default ({ app, $axios, store, redirect }, inject) => {
  $axios.defaults.baseURL = '项目地址'
  $axios.defaults.timeout = 5000

  // 请求拦截
  $axios.onRequest((config) => {
  	// 本项目token 存储在vuex里面 
    const token = store.state.user.token
    if (token) config.headers.token= token
  })

  // 服务器返回异常拦截
  $axios.onError((error) => {
    return error
  })

  // 接口数据返回拦截
  $axios.onResponse((response) => {
  	// 状态码异常 跳转到登陆
	// redirect('/login')
      return response
  })
	const API = {}
	  for (const i in apiEntire) {
	  	// 调用api时候的参数 
	  	// 第一位为 post参数 第二位为get参数
	    API[i] = function(data = '', params = '') {
	      const { url, method, headers } = { ...apiEntire[i] }
	      return $axios({
	        url,
	        method,
	        headers,
	        data,
	        params
	      })
	    }
	  }
	  app.api = API
	  inject('api', API)
}

axios封装完后 接下来就是使用方法

使用方法

单个接口使用 asyncData 里面使用(不建议)

asyncData(ctx,callback){
	ctx.$api.recommendNews('post参数','get参数').then(res=>{
		callback(null,{list:res.data})
	}),
}

多个接口使用 asyncData 里面使用(建议)

async asyncData(ctx) {
    const [news, exhibitionList] = await Promise.all([
      // 新闻接口
      ctx.$api.News(),
      ctx.$api.Fair('', { size: 3})
    ])
    return {
      news: news.data.data,
      exhibitionList: exhibitionList.data.records
    }
  },

普通方法使用

this.$api.codeCheckApi('post参数','get参数').then((res) => {
	// 业务逻辑代码
})

Nuxt更多踩坑合集

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐