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},
     ......
  ],

 

posted @ 2022-08-23 17:34  忙着可爱呀~  阅读(420)  评论(0)    收藏  举报