zoukankan      html  css  js  c++  java
  • 使用typescript封装axios

    使用typescript封装axios

    这个axios封装,因为是用在vue3的demo里面的,为了方便,在vue3的配置里面按需加载element-plus

    封装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)
    
        /* 请求拦截  this.service.interceptors.request.use(config => config, error => Promise.reject(error))*/
        this.service.interceptors.request.use((config: AxiosRequestConfig) => {
          /* 业务逻辑
          1. 开启全屏loading动画
          2. 数据加密config.data
          3. 请求头加上token,结合vuex或localstorage:
              if(store.getters.token) config.headers['x-token'] = store.getters.token
              else 重定向
          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 => {
          /* 请求错误 
          1. 关闭全屏loading动画
          2. 重定向到错误页
          */
          loading.close()
          return Promise.reject(error) // 为了可以在代码中catch到错误信息
        })
    
    
        /* 响应拦截   this.service.interceptors.response.use(response => response.data, error => Promise.reject(error))*/
        this.service.interceptors.response.use((response: AxiosResponse<any>) => {
          /* 
          1. 关闭全屏loading动画
          2. 数据解密
          3. 根据 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('请求失败',)
          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: 接口返回数据的类型定义
    export interface IResponseData<T> {
      status: number;
      message?:string;
      data:T;
      code: string;
    }
    

    axios的使用

    • list.vue:
      const { data } = await http.get<IList>('/goods/list', queryForm.value) list.value = data.list
    <template lang="pug">
    //- 查询form
    el-form(:inline="true" :model="queryForm" size="small" label-position="left")
      el-form-item
        el-button(type="primary" @click="operate")
          | 新增
      el-form-item(label="商品编号")
        el-input(v-model="queryForm._id")
      el-form-item(label="商品名")
        el-input(v-model="queryForm.goodName")
      el-form-item(label="数量")
        el-input(v-model="queryForm.count")
      el-form-item(label="详情")
        el-input(v-model="queryForm.des")
      el-form-item
        el-button(type="primary" @click="query")
          | 查询
    
    //- 列表
    el-table(:data="list" center size="mini")
      el-table-column(prop="goodName" label="商品名")
      el-table-column(prop="count" label="数量")
      el-table-column(prop="des" label="详情")
      el-table-column(label="操作")
        template(#default="props")
          el-button(type="primary" size="small" @click="operate(props.row)")
            | 编辑
          el-button(type="danger" size="small" @click="operate(props.row, true)")
            | 删除
    
    //- 新增、编辑
    el-drawer(v-model="detailShow" :title="editShow === true ? '编辑' : '新增'" direction="rtl")
      el-form(:model="detailForm" size="small" label-width="80px" label-position="left")
        //- el-form-item(label="商品编号" required v-if="false")
        el-form-item(label="商品编号" required v-if="log(editShow)")
          el-input(v-model="detailForm._id" readonly)
        el-form-item(label="商品名" required) 
          el-input(v-model="detailForm.goodName")
        el-form-item(label="数量")
          el-input(v-model="detailForm.count")
        el-form-item(label="详情")
          el-input(v-model="detailForm.des")
        el-form-item
          el-button(type="primary" size="small" @click="submit")
            | 确定
    </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: '操作成功',
            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[]
    }
    
  • 相关阅读:
    python3.5: error while loading shared libraries: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory
    php回溯
    PHPredis长连接pconnect
    php操作redis出现不报错就退出
    MSMQ消息队列
    消息队列使用的四种场景介绍(准载)
    Spring MVC参数封装传递
    Spring MVC配置实例
    .NET项目中使用PostSharp
    C#进阶系列——AOP
  • 原文地址:https://www.cnblogs.com/shine-lovely/p/15469625.html
Copyright © 2011-2022 走看看