Heim > Web-Frontend > View.js > Hauptteil

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

王林
Freigeben: 2023-05-18 10:22:14
nach vorne
905 Leute haben es durchsucht

    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
    Nach dem Login kopieren

    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)
      Nach dem Login kopieren

      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 })
      }
      Nach dem Login kopieren

      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>
      Nach dem Login kopieren
      Nach dem Login kopieren
    • zu definieren 2. Abhängigkeitsinstallation und -verarbeitung von Mock.js

      1. Installieren Sie Abhängigkeiten
    • # 安装
      npm install mockjs --save
      Nach dem Login kopieren
    . 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;;
    Nach dem Login kopieren
    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
            }
        }
    }
    Nach dem Login kopieren

    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
    }
    Nach dem Login kopieren
    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
    Nach dem Login kopieren

    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;);
    Nach dem Login kopieren

    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>
    Nach dem Login kopieren
    Nach dem Login kopieren
    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!

    Verwandte Etiketten:
    Quelle:yisu.com
    Erklärung dieser Website
    Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
    Beliebte Tutorials
    Mehr>
    Neueste Downloads
    Mehr>
    Web-Effekte
    Quellcode der Website
    Website-Materialien
    Frontend-Vorlage