Vue3에서 전역적으로 axios를 구성하는 두 가지 방법

시리즈를 녹화하면서 보고 배우는 Vue3가 막 도착했습니다. 오늘은 Vue3의 Composition API(결합 API)에서 Axios를 사용하는 방법을 여러분과 함께 배우고 녹화하겠습니다!

 

목차

1. Vue2의 전역 참조 방법 검토

  1. 간단한 프로젝트를 위한 글로벌 레퍼런스

2. 복잡한 프로젝트의 3단계 패키징

2. Vue3에서 사용하기 

1. 제공/주입 방법

2. getCurrentInstance 통합 API 도입


 

 

1. Vue2의 전역 참조 방법 검토

  1. 간단한 프로젝트를 위한 글로벌 레퍼런스

    몇 페이지만 사용한다면 너무 복잡한 설정 없이 main.js 에 바로 마운트 가능

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'

   페이지 사용

methods:{


    getData(){

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

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

}

2. 복잡한 프로젝트의 3단계 패키징

  ① 새로운 util/request.js 생성(글로벌 Axios 설정, 요청 차단, 응답 차단 등)

        VFrame에 대한 질문이 있는 학생은   il8n을 사용하지 않고 프런트 엔드로 이동할 수 있습니다.다국어를 우아하게 달성하는 방법은 무엇입니까?

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;

 ② 새로운 api/login.js 생성(페이지 구성에 필요한 api)

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'
  })
}

  ③ 페이지 이용 안내

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

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

2. Vue3에서 사용하기 

 위의 Vue2에서 axios 사용을 검토한 후 학습을 위해 Vue3에서 axios 사용(간단한 데모, 전경의 Vue3, 배경의 node.js)을 살펴보겠습니다!

1. 제공/주입 방법

    ① 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.provide('$axios', axios)
app.use(store).use(router).mount('#app');

    ② inject를 사용하여 사용할 페이지를 수락합니다.

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 }

  }

}

이는 provide를 사용하여 배포하는 것으로 Vue2의 격차와 크게 다르지 않습니다. 

 

2. getCurrentInstance 통합 API 도입

 ① 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');

/* 전역 객체 마운트 */
app.config.globalProperties.$axios = axios;

핵심은 위 문장

② Composition Api -- getCurrentInstance를 사용하여 사용해야 하는 페이지 가져오기

<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>

아래 그림에서 볼 수 있듯이 API를 두 번 호출했습니다. 

사실 Composition API의 getCurrentInstance 메소드를 통해서는 두가지 방법이 있습니다.

 1. getCurrentInstance 메서드를 통해 현재 인스턴스를 얻은 다음 현재 인스턴스에 따라 전역 인스턴스 개체 appContext를 찾은 다음 전역 인스턴스의 config.globalProperties를 가져옵니다.        

const currentInstance = getCurrentInstance();

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

 2. getCurrentInstance 메서드를 통해 컨텍스트를 가져옵니다. 여기서 프록시는 이것과 동일합니다.

const currentInstance = getCurrentInstance();

const { proxy } = currentInstance;

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

 


끝~~~ 


 

추천

출처blog.csdn.net/weixin_56650035/article/details/125610295