Detailed example of using typescript to encapsulate axios in Vue3

Detailed example of using typescript to encapsulate axios in Vue3

This axios package is used in the vue3 demo. For convenience, element-plus is loaded on demand in the vue3 configuration.

Encapsulating Axios

http.ts

import axios, { AxiosRequestConfig, AxiosRequestHeaders, AxiosResponse } from 'axios'
import { IResponseData } from '@/types'
import { ElMessage, ElLoading, ILoadingInstance } from 'element-plus'

type TAxiosOption = {
  baseURL: string;
  timeout: number;
}

const config = {
  baseURL: '/',
  timeout: 120000
}

let loading: ILoadingInstance;

class Http {
  //service: AxiosInstance;
  service;
  constructor(config: TAxiosOption) {
    this.service = axios.create(config)

    /* Request interception this.service.interceptors.request.use(config => config, error => Promise.reject(error))*/
    this.service.interceptors.request.use((config: AxiosRequestConfig) => {
      /* Business logic 1. Enable full-screen loading animation 2. Data encryption config.data
      3. Add token to the request header, combined with vuex or localstorage:
          if (store.getters.token) config.headers['x-token'] = store.getters.token
          else redirect 4. …
      */
      loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        spinner: 'el-icon-loading',
        background: 'rgba(255, 255, 255, 0.7)',
      })

      if (localStorage.getItem('token')) {
        (config.headers as AxiosRequestHeaders).authorization = localStorage.getItem('token') as string
      }

      return config
    }, error => {
      /* Request error 1. Close full-screen loading animation 2. Redirect to error page */
      loading.close()
      return Promise.reject(error) // In order to catch the error message in the code})


    /* Response interception this.service.interceptors.response.use(response => response.data, error => Promise.reject(error))*/
    this.service.interceptors.response.use((response: AxiosResponse<any>) => {
      /* 
      1. Close the full-screen loading animation 2. Data decryption 3. Perform different error handling based on response.data.code 4. …
      */
      loading.close()

      const data = response.data
      const { code } = data

      if (code !== '000000') {
        ElMessage.error(data.message)
        return Promise.reject(data)
      }
      return response.data
    }, error => {
      loading.close()
      ElMessage.error('Request failed',)
      return Promise.reject(error)
    })
  }
  get<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
    return this.service.get(url, { params, ..._object })
  }
  post<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
    return this.service.post(url, params, _object)
  }
  put<T>(url: string, params?: object, _object = {}): Promise<IResponseData<T>> {
    return this.service.put(url, params, _object)
  }
  delete<T>(url: string, params?: any, _object = {}): Promise<IResponseData<T>> {
    return this.service.delete(url, { params, ..._object })
  }
}

export default new Http(config)

types/index.ts: Type definition of the data returned by the interface

export interface IResponseData<T> {
  status: number;
  message?:string;
  data:T;
  code: string;
}

Use of axios

list.vue:

const { data } = await http.get<IList>('/goods/list', queryForm.value) list.value = data.list

<template lang="pug">
//- Query form
el-form(:inline="true" :model="queryForm" size="small" label-position="left")
  el-form-item
    el-button(type="primary" @click="operate")
      | Add el-form-item(label="Product Number")
    el-input(v-model="queryForm._id")
  el-form-item(label="Product Name")
    el-input(v-model="queryForm.goodName")
  el-form-item(label="quantity")
    el-input(v-model="queryForm.count")
  el-form-item(label="Details")
    el-input(v-model="queryForm.des")
  el-form-item
    el-button(type="primary" @click="query")
      | Query //- List el-table(:data="list" center size="mini")
  el-table-column(prop="goodName" label="Product Name")
  el-table-column(prop="count" label="quantity")
  el-table-column(prop="des" label="Details")
  el-table-column(label="operation")
    template(#default="props")
      el-button(type="primary" size="small" @click="operate(props.row)")
        | Edit el-button(type="danger" size="small" @click="operate(props.row, true)")
        | Delete //- Add, edit el-drawer(v-model="detailShow" :title="editShow === true ? 'Edit' : 'Add'" direction="rtl")
  el-form(:model="detailForm" size="small" label-width="80px" label-position="left")
    //- el-form-item(label="Product Number" required v-if="false")
    el-form-item(label="Product Number" required v-if="log(editShow)")
      el-input(v-model="detailForm._id" readonly)
    el-form-item(label="Product Name" required) 
      el-input(v-model="detailForm.goodName")
    el-form-item(label="quantity")
      el-input(v-model="detailForm.count")
    el-form-item(label="Details")
      el-input(v-model="detailForm.des")
    el-form-item
      el-button(type="primary" size="small" @click="submit")
        | OK</template>

<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import { ElMessage } from 'element-plus'
import { IGoodInfo, IList } from '@/types/goods'
import http from '@/http'

export default defineComponent({
  name: 'Home',
  setup() {
    const list = ref<IGoodInfo[]>([])

    const queryForm = ref({ goodName: '', count: '', _id: '', des: '' })
    const detailForm = ref({ goodName: '', count: '', _id: '', des: '' })
    const detailShow = ref(false)
    const editShow = ref(false)

    query()


   	async function query() {
      const { data } = await http.get<IList>('/goods/list', queryForm.value)
      list.value = data.list
    }

    async function operate(form?: IGoodInfo, flag?: true) {
      if (!form) {
        detailShow.value = true
        editShow.value = false
        detailForm.value = { goodName: '', count: '', _id: '', des: '' }
      } else if (!flag) {
        detailShow.value = true
        editShow.value = true
        detailForm.value = { ...form }
      } else {
        await http.delete('/goods/delete', { _id: form._id })
        query()
      }
    }

    async function submit() {
      if (detailForm.value._id) {
        await http.put('/goods/edit', detailForm.value)
      }else{
        await http.put('/goods/edit', detailForm.value)
      }

      detailShow.value = false
      ElMessage({
        message: 'Operation successful',
        type: 'success',
      })
      query()
    }


    function log(params:any) {
     console.log(params);
     return params
    }

    return {
      detailShow,
      editShow,
      list,
      queryForm,
      detailForm,
      query,
      operate,
      submit,
      log
    }
  }
});
</script>

types/goods.ts

export interface IGoodInfo {
  _id: string;
  goodName: string;
  count: string;
  des: string
}

export interface IList {
  list: IGoodInfo[]
}

This is the end of this article about using typescript to encapsulate axios. For more related typescript encapsulation content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue3 + TypeScript Development Summary
  • Practical record of Vue3 combined with TypeScript project development
  • How to use vue3+TypeScript+vue-router
  • Vue3 TypeScript implements useRequest details

<<:  Detailed explanation of the use of grid properties in CSS

>>:  HTML+CSS implementation code for rounded rectangle

Recommend

...

JavaScript implements circular progress bar effect

This article example shares the specific code of ...

Simple method to install mysql under linux

When searching online for methods to install MySQ...

Our thoughts on the UI engineer career

I have been depressed for a long time, why? Some t...

Solution to the Chinese garbled characters problem in MySQL under Ubuntu

Find the problem I have been learning Django rece...

About Docker security Docker-TLS encrypted communication issues

Table of contents 1. Security issues with Docker ...

How to run Python script on Docker

First create a specific project directory for you...

WeChat applet realizes horizontal and vertical scrolling

This article example shares the specific code for...

CSS overflow-wrap new property value anywhere usage

1. First, understand the overflow-wrap attribute ...

How to center your HTML button

How to center your HTML button itself? This is ea...

Analysis of Linux boot system methods

This article describes how to boot the Linux syst...