Nuxt axios使用及二次封装
1、安装
axios:npm install @nuxtjs/axios axios --save 代理: npm i @nuxtjs/proxy -D
2、配置 axios
>>>nuxt.config.js modules: [ '@nuxtjs/axios', "@nuxtjs/proxy", ], axios: { proxy: true, prefix: '/m/api', // baseURL proxyHeaders: false, credentials: false }, proxy: { '/m/api': { target: process.env.BASE_URL, // 代理地址 changeOrigin: true, pathRewrite: { '^/m/api': '', // 将 /api 替换掉,如果请求地址中有 /api 则不必替换 }, }, }
3、自定义环境
安装:npm install --save-dev cross-env 配置: >>>package.json "scripts": { "dev": "cross-env BASE_URL=http://yfnimg.bestsmell.cn:10011 NODE_ENV=development nuxt --port 3006", "pre": "cross-env BASE_URL=http://pre-api.yfn.com NODE_ENV=pre nuxt", "pro": "cross-env BASE_URL=https://api.yfn.com NODE_ENV=production nuxt", "build:dev": "cross-env BASE_URL=http://yfnimg.bestsmell.cn:10011 NODE_ENV=development nuxt build", "build:pre": "cross-env BASE_URL=https://pre-api.yfn.com NODE_ENV=pre nuxt build", "build:pro": "cross-env BASE_URL=https://api.yfn.com NODE_ENV=production nuxt build", "build": "nuxt build", "start": "nuxt start", "generate": "nuxt generate" } // 注:NODE_ENV环境变量将由cross-env设置
// process.env.BASE_URL -> http://yfnimg.bestsmell.cn:10011
4、直接使用
this.$axios.$get('/mall/v2/homepage/getTabV2', {}).then(res => { // 业务处理 })
5、二次封装
5.1)、统一api模块管理
示例目录: |--api |---index.js //api模块入口文件 |---apilist |---home.js //各个api接口
api/index.js: 用于导入apilist中的所有接口,
此时api/index模块导出为一个object, 参数为apilist中每个文件名,value值为对应的函数
// api->index.js 导入所有api接口 const modulesFiles = require.context("@/api/apilist", true, /\.js$/); const modules = modulesFiles.keys().reduce((modules, modulePath) => { const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, "$1"); const value = modulesFiles(modulePath); modules[moduleName] = value.default || value; return modules; }, {}); export default modules;
// api->apilist->home.js export default $axios => ({ getCarProNum() { return $axios.get(`/mall/v1/cart/userCartCount`); } });
5.2)、暴露api
// >>> plugins->api-plugin.js // 使用plugin中inject参数暴露api , // api注入到服务端context, vue实例, vuex中 import apis from "@/api/index"; export default (ctx, inject) => { var apiObject = {}; for (var i in apis) { apiObject[i] = apis[i](ctx.$axios); } //文档: https://www.nuxtjs.cn/guide/plugins //inject:注入到服务端context, vue实例, vuex中 inject("api", apiObject); };
5.3)、配置 api
//>>>nuxt.config.js plugins: [ ... '@/plugins/vant', "@/plugins/api-plugin", ],
6、api在vue文件中使用
this.$api.home.postMock({ pageNumber: 1 }).then(res => { // 业务处理 })
7、api内使用
>>> api->apilist->home.js getMock(params) { return $axios.get(`/mall/v1/cart/userCartCount`, { params: { pageNum: 1, pageSize: 20, }, config: { hasLoading: true } }); }, postMock() { return $axios.post("/mall/v1/address/getCountryByIp", { pageNum: 1, pageSize: 20, }, { config: { hasLoading: true } }); },
7、拦截器设置(按需)
7.1)、设置文件
>>>> plugins->axios.js /** * @author 小熊 * @description axios 插件 */ import Vue from 'vue' import SetHeader from '/utils/set-headers' const setHeader = new SetHeader() export default function (ctx) { const {$axios, $cookies} = ctx.app; let hasLoading = false $axios.defaults.baseURL = process.env.BASE_URL; $axios.defaults.timeout = 30000; ($axios.defaults.headers = { "Content-Type": "application/json;charset=UTF-8", }), $axios.interceptors.request.use((config, options) => { let headers = setHeader.getHeaders(ctx,config?.config) // post if (config.method == 'post') { if (config.data && config?.config?.dataType != 2) { let reData = JSON.parse(JSON.stringify(config.data)) let formData = new FormData(); Object.keys(reData).forEach(key => { formData.append(key, reData[key]) }) config.data = formData config.headers['Content-Type'] = 'application/x-www-form-urlencoded' } } // 请求头 Object.keys(headers).forEach(key => { !config.headers[key] && (config.headers[key] = headers[key]) // config.headers[key] = headers[key] }) // loading const loadingType = config?.config?.loadingType ?? 1; let loadingOptions = {}; hasLoading = config?.config?.hasLoading loadingOptions = { visible: hasLoading } loadingType == 2 && (loadingOptions.type = 2) hasLoading && Vue.prototype.$loading(loadingOptions) return config; }); $axios.interceptors.response.use(response => { const data = response?.data || {}; if(data.code != 'success') { Vue.prototype.$Toast(data.error_msg || data.error_code) } Vue.prototype.$loading(false) return data; }, (err) => { const res = err?.response?.data || {}; res.status != 401 && Vue.prototype.$Toast(res.message || res.error || 'Failed') if(res.status == 401) { ctx.app.$storage && ctx.app.$storage.remove('token') } return res }); }
7.2)、配置axios.js
>>>nuxt.config.js plugins: [ {src:"~/plugins/axios.js",ssr:true}, ...... ],