Two ways to configure axios globally in Vue3

Watching and learning while recording series, just arrived at Vue3, today I will learn and record with you how to use Axios in Vue3's Composition API (combined API)!

 

Table of contents

1. Review the global reference method of Vue2

  1. Global references for simple projects

2. Three-step packaging of complex projects

2. Use in Vue3 

1. Provide/inject mode

2. Introduction of getCurrentInstance combined API


 

 

1. Review the global reference method of Vue2

  1. Global references for simple projects

If only a few pages are used, it can be mounted directly in main.js     without too complicated configuration

import Vue from "vue";

/* 第一步下载 axios 命令:npm i axios 或者yarn add axios 或者pnpm i axios */
/* 第二步引入axios */
import axios from 'axios'


// 挂载一个自定义属性$http
Vue.prototype.$http = axios
// 全局配置axios请求根路径(axios.默认配置.请求根路径)
axios.defaults.baseURL = 'http://yufei.shop:3000'

   page use

methods:{


    getData(){

        this.$http.get('/barry').then(res=>{

            console.log('res',res)
        )}
    }

}

2. Three-step packaging of complex projects

  ① Create a new util/request.js (configure global Axios, request interception, response interception, etc.)

        Students who have questions about VFrame can move to   the front end without using il8n. How to achieve multi-language elegantly?

import axios from "axios";
import { Notification, MessageBox, Message } from "element-ui";
import store from "@/store";
import { getToken } from "@/utils/auth";
import errorCode from "@/utils/errorCode";
import Cookies from "js-cookie";
import VFrame from "../framework/VFrame.js";
import CONSTANT from '@/CONSTANT.js'

axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: process.env.VUE_APP_BASE_API,
  // 超时
  timeout: 120000
});
// request拦截器
service.interceptors.request.use(
  config => {
    // 是否需要设置 token
    const isToken = (config.headers || {}).isToken === false;
    if (getToken() && !isToken) {
      config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    var cultureName = Cookies.get(CONSTANT.UX_LANGUAGE);
    if (cultureName) {
      config.headers[CONSTANT.UX_LANGUAGE] = cultureName; // 让每个请求携带自定义token 请根据实际情况自行修改
    }
    // get请求映射params参数
    if (config.method === "get" && config.params) {
      let url = config.url + "?";
      for (const propName of Object.keys(config.params)) {
        const value = config.params[propName];
        var part = encodeURIComponent(propName) + "=";
        if (value !== null && typeof value !== "undefined") {
          if (typeof value === "object") {
            for (const key of Object.keys(value)) {
              let params = propName + "[" + key + "]";
              var subPart = encodeURIComponent(params) + "=";
              url += subPart + encodeURIComponent(value[key]) + "&";
            }
          } else {
            url += part + encodeURIComponent(value) + "&";
          }
        }
      }
      url = url.slice(0, -1);
      config.params = {};
      config.url = url;
    }
    return config;
  },
  error => {
    console.log(error);
    Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  res => {
    // 未设置状态码则默认成功状态
    const code = res.data.code || 200;
    // 获取错误信息
    const msg = errorCode[code] || res.data.msg || errorCode["default"];
    if (code === 401) {
      MessageBox.alert(
        VFrame.l("SessionExpired"),
        VFrame.l("SystemInfo"),
        {
          confirmButtonText: VFrame.l("Relogin"),
          type: "warning"
        }
      ).then(() => {
        store.dispatch("LogOut").then(() => {
          location.href = "/index";
        });
      });
    } else if (code === 500) {
      Message({
        message: msg,
        type: "error"
      });
      if (res.data.data) {
        console.error(res.data.data)
      }
      return Promise.reject(new Error(msg));
    } else if (code !== 200) {
      Notification.error({
        title: msg
      });
      return Promise.reject("error");
    } else {
      if (res.data.uxApi) {
        if (res.data.success) {
          return res.data.result;
        } else {
          Notification.error({ title: res.data.error });
          console.error(res);
          return Promise.reject(res.data.error);
        }
      } else {
        return res.data;
      }
    }
  },
  error => {
    console.log("err" + error);
    let { message } = error;
    if (message == "Network Error") {
      message = VFrame.l("TheBackEndPortConnectionIsAbnormal");
    } else if (message.includes("timeout")) {
      message = VFrame.l("TheSystemInterfaceRequestTimedOut");
    } else if (message.includes("Request failed with status code")) {
      message =
        VFrame.l("SystemInterface") +
        message.substr(message.length - 3) +
        VFrame.l("Abnormal");
    }
    Message({
      message: VFrame.l(message),
      type: "error",
      duration: 5 * 1000
    });
    return Promise.reject(error);
  }
);

export default service;

 ② Create a new api/login.js (the api needed to configure the page)

import request from '@/utils/request'

// 登录方法
export function login(username, password,shopOrgId,counter, code, uuid) {
  const data = {
    username,
    password,
    shopOrgId,
    counter,
    uuid
  }
  return request({
    url: '/login',
    method: 'post',
    data: data
  })
}

// 获取用户详细信息
export function getInfo() {
  return request({
    url: '/getInfo',
    method: 'get'
  })
}

// 退出方法
export function logout() {
  return request({
    url: '/logout',
    method: 'post'
  })
}

  ③ Introduction of page usage

import { login } from "@/api/login.js"

接下来不用多说,相信大家已经会使用了

2. Use in Vue3 

 After reviewing the use of axios in Vue2 above, let's take a look at the use of axios in Vue3 (simple demo, Vue3 in the foreground, and node.js in the background), just for learning!

1. Provide/inject mode

    ① Use provide in main.js to pass in

import {
    createApp
} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import "lib-flexible/flexible.js"

import axios from "@/util/request.js"

const app = createApp(App);



app.provide('$axios', axios)
app.use(store).use(router).mount('#app');

    ② Use inject to accept the pages that need to be used

import { ref, reactive, inject, onMounted} from "vue";

export default {
  setup() {

    const $axios = inject("$axios");

    const getData = async () => {
      data = await $axios({ url: "/one/data" });
      console.log("data", data);
    };

    onMounted(() => {
        
      getData()

    })
    

    return { getData }

  }

}

This is to use provide to make a distribution, which is not much different from the gap in Vue2. 

 

2. Introduction of getCurrentInstance combined API

 ① mount in main.js

import {
    createApp
} from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import "lib-flexible/flexible.js"

import axios from "@/util/request.js"

const app = createApp(App);

/* 挂载全局对象 */
app.config.globalProperties.$axios = axios;


app.use(store).use(router).mount('#app');

/* Mount global objects */
app.config.globalProperties.$axios = axios;

the key point is the above sentence

② Use Composition Api -- getCurrentInstance to get the page that needs to be used

<script>
import { reactive, onMounted, getCurrentInstance } from "vue";
export default {
  setup() {
    let data = reactive([]);
    /**
     * 1. 通过getCurrentInstance方法获取当前实例
     * 再根据当前实例找到全局实例对象appContext,进而拿到全局实例的config.globalProperties。
     */
    const currentInstance = getCurrentInstance();
    const { $axios } = currentInstance.appContext.config.globalProperties;

    /**
     * 2. 通过getCurrentInstance方法获取上下文,这里的proxy就相当于this。
     */

    const { proxy } = currentInstance;


    const getData = async () => {
      data = await $axios({ url: "/one/data" });
      console.log("data", data);
    };

    const getData2 = async () => {
      data = await proxy.$axios({ url: "/one/data" });
      console.log("data2", data);
    };

    onMounted(() => {

      getData()

    });
    return { getData };
  },
};
</script>

As you can see in the figure below, we did call the API twice 

In fact, through the getCurrentInstance method in the Composition API, there are two ways

 1. Obtain the current instance through the getCurrentInstance method, and then find the global instance object appContext according to the current instance, and then get the config.globalProperties of the global instance.        

const currentInstance = getCurrentInstance();

const { $axios } = currentInstance.appContext.config.globalProperties;

 2. Obtain the context through the getCurrentInstance method, where the proxy is equivalent to this.

const currentInstance = getCurrentInstance();

const { proxy } = currentInstance;

const getData2 = async () => {
      data = await proxy.$axios({ url: "/one/data" });
      console.log("data2", data);
};

 


end~~~ 


 

Guess you like

Origin blog.csdn.net/weixin_56650035/article/details/125610295