Heim >Web-Frontend >View.js >Was ist die Methode, Axios zu kapseln und Mock.js mit vue3 und ts zu verwenden?

Was ist die Methode, Axios zu kapseln und Mock.js mit vue3 und ts zu verwenden?

王林
王林nach vorne
2023-05-18 10:22:141104Durchsuche

    Vorwort

    Wir sollten auf die Unterscheidung zwischen Axios und Ajax achten:

    Ajax ist ein allgemeiner Begriff für Technologie. Der technische Inhalt umfasst: HTML oder XHTML, CSS, JavaScript, DOM, XML, XSLT und die Am wichtigsten ist XMLHttpRequest, wobei die asynchrone Datenübertragung (HTTP-Anfrage) zwischen dem Browser und dem Server verwendet wird, um eine lokale Aktualisierung zu erreichen. Die Verwendung basiert auf XMLHttpRequest Bibliothek

    Haupttechnologie-Stack: vue3, ts, axios, mock.js, elementPlus

    1. Installation und Verarbeitung von Axios-Abhängigkeiten

    1. Die Verwendung asynchroner Netzwerkanforderungen ist definitiv untrennbar mit Laden, Nachrichten usw. verbunden Eingabeaufforderungen. Heute verwenden wir es mit elementPlus;

    // 安装axios 
    npm install axios --save
     
    // 安装 elementPlus
    npm install element-plus --save

    2. Erstellen Sie im utils-Verzeichnis unter dem src-Verzeichnis ein neues request.ts, das Datenformat muss im Voraus definiert werden :

    Definieren Sie die Rückgabe der Anforderungsdaten. Das Format muss im Voraus bestätigt werden.

    Definieren Sie die grundlegenden Konfigurationsinformationen von Axios Token, mehrsprachig usw.)

    • Antwort-Interceptor: Gibt den Ort zurück, an dem die Daten zuerst ankommen, wo wir Ausnahmeinformationen verarbeiten können (z. B. Code 401 leitet zur Anmeldung weiter, Code 500 löst eine Fehlermeldung aus)

    • import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from "axios";
      import { ElMessage, ElLoading, ElMessageBox } from "element-plus";
       
      // response interface { code, msg, success }
      // 不含 data
      interface Result {
          code: number,
          success: boolean,
          msg: string
      }
       
      // request interface,包含 data
      interface ResultData<T = any> extends Result {
          data?: T
      }
       
      enum RequestEnums {
          TIMEOUT = 10000, // 请求超时 request timeout
          FAIL = 500, // 服务器异常 server error
          LOGINTIMEOUT = 401, // 登录超时 login timeout
          SUCCESS = 200, // 请求成功 request successfully
      }
       
      // axios 基础配置
      const config = {
          // 默认地址,可以使用 process Node内置的,项目根目录下新建 .env.development
          baseURL: process.env.VUE_APP_BASE_API as string,
          timeout: RequestEnums.TIMEOUT as number, // 请求超时时间
          withCredentials: true, // 跨越的时候允许携带凭证
      }
       
      class Request {
          service: AxiosInstance;
       
          constructor(config: AxiosRequestConfig) {
              // 实例化 serice
              this.service = axios.create(config);
       
              /**
               * 请求拦截器
               * request -> { 请求拦截器 } -> server
               */
              this.service.interceptors.request.use(
                  (config: AxiosRequestConfig) => {
                      const token = localStorage.getItem(&#39;token&#39;) ?? &#39;&#39;;
                      return {
                          ...config,
                          headers: {
                              &#39;customToken&#39;: "customBearer " + token
                          }
                      }
                  },
                  (error: AxiosError) => {
                      // 请求报错
                      Promise.reject(error)
                  }
              );
       
              /**
               * 响应拦截器
               * response -> { 响应拦截器 } -> client
               */
              this.service.interceptors.response.use(
                  (response: AxiosResponse) => {
                      const { data, config } = response;
                      if (data.code === RequestEnums.LOGINTIMEOUT) {
                          // 表示登录过期,需要重定向至登录页面
                          ElMessageBox.alert("Session expired", "System info", {
                              confirmButtonText: &#39;Relogin&#39;,
                              type: &#39;warning&#39;
                          }).then(() => {
                              // 或者调用 logout 方法去处理
                              localStorage.setItem(&#39;token&#39;, &#39;&#39;);
                              location.href = &#39;/&#39;
                          })
                      }
                      if (data.code && data.code !== RequestEnums.SUCCESS) {
                          ElMessage.error(data);
                          return Promise.reject(data);
                      }
                      return data
                  },
                  (error: AxiosError) => {
                      const { response } = error;
                      if (response) {
                          this.handleCode(response.status);
                      }
                      if (!window.navigator.onLine) {
                          ElMessage.error("网络连接失败,请检查网络");
                          // 可以重定向至404页面
                      }
                  }
       
              )
          }
       
          public handleCode = (code: number): void => {
              switch (code) {
                  case 401:
                      ElMessage.error("登陆失败,请重新登录");
                      break;
                  case 500:
                      ElMessage.error("请求异常,请联系管理员");
                      break;
                  default:
                      ElMessage.error(&#39;请求失败&#39;);
                      break;
              }
          }
       
          // 通用方法封装
          get<T>(url: string, params?: object): Promise<ResultData<T>> {
              return this.service.get(url, { params });
          }
       
          post<T>(url: string, params?: object): Promise<ResultData<T>> {
              return this.service.post(url, params);
          }
          put<T>(url: string, params?: object): Promise<ResultData<T>> {
              return this.service.put(url, params);
          }
          delete<T>(url: string, params?: object): Promise<ResultData<T>> {
              return this.service.delete(url, { params });
          }
      }
       
      export default new Request(config)

      3. Tatsächliche Verwendung
    • src-Verzeichnis Fügen Sie api/index.ts hinzu

    • Definieren Sie den Parametertyp der Anfrage

    Definieren Sie den spezifischen Parametertyp der Antwort

    Hier verwenden wir Namespace in ts für die tatsächliche Entwicklung Viele unserer APIs haben möglicherweise die gleichen Namen mit unterschiedlichen Bedeutungen, daher verwenden wir Namespace, um
    • import request from "@/utils/request";
       
      namespace User {
          // login
          export interface LoginForm {
              userName: string,
              password: string
          }
      }
       
       
      export namespace System {
       
       
          export interface Info {
              path: string,
              routeName: string
          }
       
       
          export interface ResponseItem {
              code: number,
              items: Array<Sidebar>,
              success: boolean
          }
       
          export interface Sidebar {
              id: number,
              hashId: string | number,
              title: string,
              routeName: string,
              children: Array<SidebarItem>,
          }
       
          export interface SidebarItem {
              id: number,
              parentId: number,
              hashId: string | number,
              title: string,
          }
      }
       
      export const info = (params: System.Info) => {
          // response 
          if (!params || !params.path) throw new Error(&#39;Params and params in path can not empty!&#39;)
          // 这里因为是全局的一个info,根据路由地址去请求侧边栏,所需不用把地址写死
          return request.post<System.Sidebar>(params.path, { routeName: params.routeName })
      }

      Aufruf in der Vue-Datei
    • <script lang="ts" setup name="Sidebar">
      import { ref, reactive, onBeforeMount } from "vue"
      import { info } from "@/api"
      import { useRoute } from "vue-router"
      const route = useRoute();
       
      let loading = ref<boolean>(false);
      let sidebar = ref<any>({});
       
      const _fetch = async (): Promise<void> => {
          const routeName = route.name as string;
          const path = &#39;/&#39; + routeName.replace(routeName[0], routeName[0].toLocaleLowerCase()) + &#39;Info&#39;
          try {
              loading.value = true;
              const res = await info({ path, routeName });
              if (!res || !res.data) return;
              sidebar.value = res.data;
          } finally {
              loading.value = false
          }
      }
       
      onBeforeMount(() => {
          _fetch();
      })
       
      </script>
    • zu definieren 2. Abhängigkeitsinstallation und -verarbeitung von Mock.js

      1. Installieren Sie Abhängigkeiten
    • # 安装
      npm install mockjs --save
    . Bei Verwendung in ts müssen wir das Modul in die Datei shims-vue.d.ts einfügen, da sonst Probleme mit der Einführung von Fehlern auftreten

    /* eslint-disable */
    declare module &#39;*.vue&#39; {
      import type { DefineComponent } from &#39;vue&#39;
      const component: DefineComponent<{}, {}, any>
      export default component
    }
     
    declare module &#39;mockjs&#39;;
    2. Erstellen Sie die für das neue Modul erforderlichen Dateien Mock

    index.ts (gehört zur globalen Konfigurationsdatei von Mockjs), Mockjs/javaScript/index.ts (spezifische Datendatei), diese beiden müssen beachtet werden, die anderen müssen nicht beachtet werden

    1. Erstellen Sie eine neue Mockjs/javaScript/index.ts (spezifische Datendatei)

    Da es sich bei den Daten hier hauptsächlich um Seitenleistendaten handelt, die alle fest sind, werden die Regeln von Mockjs nicht zum Generieren von Daten verwendet

    import { GlobalSidebar, Sidebar } from "../../sidebar";
     
    namespace InfoSidebar {
        export type InfoSidebarParams = {
            body: string,
            type: string,
            url: string
        }
    }
     
    const dataSource: Array<GlobalSidebar> = [
        {
            mainTitle: &#39;JavaScript基础问题梳理&#39;,
            mainSidebar: [
                {
                    id: 0,
                    hashId: &#39;This&#39;,
                    title: &#39;this指向&#39;,
                    routeName: &#39;JsBasic&#39;,
                    children: [
                        {
                            id: 1,
                            parentId: 0,
                            hashId: &#39;GlobalFunction&#39;,
                            title: &#39;全局函数&#39;
                        },
                        {
                            id: 2,
                            parentId: 0,
                            hashId: &#39;ObjectMethod&#39;,
                            title: &#39;对象方法&#39;
                        },
                        {
                            id: 3,
                            parentId: 0,
                            hashId: &#39;Constructor&#39;,
                            title: &#39;构造函数&#39;
                        },
                        {
                            id: 4,
                            parentId: 0,
                            hashId: &#39;SetTimeout&#39;,
                            title: &#39;定时器、回调函数&#39;
                        },
                        {
                            id: 5,
                            parentId: 0,
                            hashId: &#39;EventFunction&#39;,
                            title: &#39;事件函数&#39;
                        },
                        {
                            id: 6,
                            parentId: 0,
                            hashId: &#39;ArrowFunction&#39;,
                            title: &#39;箭头函数&#39;
                        },
                        {
                            id: 7,
                            parentId: 0,
                            hashId: &#39;CallApplyBind&#39;,
                            title: &#39;call、apply、bind&#39;
                        },
                    ]
                },
                {
                    id: 2,
                    hashId: &#39;DeepClone&#39;,
                    title: &#39;深拷贝和浅拷贝&#39;,
                    routeName: &#39;JsBasic&#39;,
                    children: []
                }
            ]
        },
    ];
     
    export default {
        name: &#39;jsBasicInfo&#39;,
        jsBasicInfo(params: InfoSidebar.InfoSidebarParams) {
            const param = JSON.parse(params.body)
            if (!param) throw new Error("Params can not empty!");
            const data = dataSource.find((t: GlobalSidebar) => {
                return t.mainSidebar.filter((x: Sidebar) => {
                    return x.routeName === param.routeName
                })
            })
            return {
                data,
                success: true,
                code: 200
            }
        }
    }

    Sidebar.ts

    /**
     * @param { number } id Unique value
     * @param { string } hashId href Unique value
     * @param { string } title show current title
     * @param { string } routeName page find data
     */
     
    interface GlobalSidebar {
        mainTitle: string,
        mainSidebar: Array<Sidebar>
    }
     
    interface Sidebar {
        id: number,
        hashId: string | number,
        title: string,
        routeName: string,
        children: Array<SidebarItem>,
    }
     
    interface SidebarItem {
        id: number,
        parentId: number,
        hashId: string | number,
        title: string,
    }
     
    export {
        GlobalSidebar,
        Sidebar,
        SidebarItem
    }
    Was ist die Methode, Axios zu kapseln und Mock.js mit vue3 und ts zu verwenden?2. Erstellen Sie ein neues Mockjs/index.ts

    import Mock from "mockjs";
    import jsBasicInfo from "./tpl/javaScript/index";
    const requestMethod = &#39;post&#39;;
    const BASE_URL = process.env.VUE_APP_BASE_API;
    const mocks = [jsBasicInfo];
     
    for (let i of mocks) {
        Mock.mock(BASE_URL + &#39;/&#39; + i.name, requestMethod, i.jsBasicInfo);
    }
     
    export default Mock

    3. Main.ts führt

    import { createApp } from &#39;vue&#39;
    import App from &#39;./App.vue&#39;
     
    if(process.env.NODE_ENV == &#39;development&#39;){
        require(&#39;./mockjs/index&#39;)
    }
     
    const app = createApp(App);
    app.mount(&#39;#app&#39;);

    Tatsächlich ist es der Code, der gerade axios

    <script lang="ts" setup name="Sidebar">
    import { ref, reactive, onBeforeMount } from "vue"
    import { info } from "@/api"
    import { useRoute } from "vue-router"
    const route = useRoute();
     
    let loading = ref<boolean>(false);
    let sidebar = ref<any>({});
     
    const _fetch = async (): Promise<void> => {
        const routeName = route.name as string;
        const path = &#39;/&#39; + routeName.replace(routeName[0], routeName[0].toLocaleLowerCase()) + &#39;Info&#39;
        try {
            loading.value = true;
            const res = await info({ path, routeName });
            if (!res || !res.data) return;
            sidebar.value = res.data;
        } finally {
            loading.value = false
        }
    }
     
    onBeforeMount(() => {
        _fetch();
    })
     
    </script>
    aufgerufen hat

    Das obige ist der detaillierte Inhalt vonWas ist die Methode, Axios zu kapseln und Mock.js mit vue3 und ts zu verwenden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen