• 统一加载整个目录中的 API


    统一加载整个目录中的 API

    背景:接手的项目已经有一个 api 目录以使用方式如下表示。

    src/api:.
    │  logs.js
    │
    ├─aiplatform
    │      application.js
    │      label.js
    ├─assist
    │      assist.js
    │
    ├─base
    │      region.js
    │
    ├─classify
    │  ├─dialogue
    │  │      chat.js
    │  │      data.js
    │  │
    │  ├─label
    │  │      index.js
    │  │
    │  └─mould
    │          list.js
    │          test.js
    │
    ├─common
    │      common.js
    │
    ├─desk
    │      notice.js
    

    其中的 js 文件内容示例:

    import request from '@/router/axios';
    
    export const getList = (current, size, params) => {
      return request({
        url: '/api/blade-desk/notice/list',
        method: 'get',
        params: {
          ...params,
          current,
          size,
        }
      })
    }
    
    export const remove = (ids) => {
      return request({
        url: '/api/blade-desk/notice/remove',
        method: 'post',
        params: {
          ids,
        }
      })
    }
    
    

    所有接口引用方式示例:

    import { getList } from "@/api/aiplatform/application";
    getList(cnt).then( res => {
      console.log(res.data.data)
    })
    

    个人感觉之种方式不太间接,想逐步修改它们。

    • 目录层级划分太多,管理起来十分繁琐
    • 接口声明没有把 method 和 url 以及参数进行封装,声明一个接口得首先一陀代码
    • 每个使用时都必须 import { xxxx } "..."
    • 接口响应中的主要数据部分没有经过统一处理,每个使用的地方都得 res.data.data...

    修改后的调用方式

    • 直接引用,无需导入
    • 直接返回响应中的主要数据
    this.$api.aiplatform.application.getList(cnt).then( res => {
      console.log(res) //
    })
    

    实现方式

    在 api 目录下创建 index.js 文件,内容为:

    import lodash from 'lodash'
    const files = require.context('./', true, /.js$/);
    const apiMaps = {}
    files.keys().forEach(key => {
      const path = key.replace(/^./|.js$/g, ``).replace(///g, `.`)
      const obj = files(key) // 如果文件内容写了 export default, 那么这里是 files(key).default
      const objRes = {}
      Object.keys(obj).forEach(key => { // 对每个 API 统一添加拦截器, 本来这个功能应该在 axios 的, 为了不影响已有的代码,另开了一个功能
        let fn = obj[key]
        objRes[key] = (...arg) => {
          return new Promise((resove, reject) => {
            fn(...arg).then(res => {
              const inRes = (res) => { // 响应拦截器
                if(res.status === 200) {
                  return res.data.data
                } else {
                  throw new Error(res.msg)
                }
              }
              resove(inRes(res))
            }).catch(err => {
              reject(err)
            })
          })
        }
      })
      lodash.set(apiMaps, path, objRes)
    })
    export default apiMaps
    
    

    在入口 main.js 中添加以下内容:

    import api from '@/api'
    Vue.prototype.$api = api
    

    然后就能在使用的地方通过 this.$api.目录.方法 的形式调用接口了,不影响原来的调用方式。

    核心知识点

    • webpack 中的 require.context
  • 相关阅读:
    关于进程间通信
    ipc (进程间通信
    为什么需要进程间通信??
    重载、重写、覆盖
    conerstone代码回滚
    重载、重写、符号冲突、扩展
    UICollectionView(一)基本概念
    UICollectionViewFlowLayout & UICollectionViewDelegateFlowLayout
    UICollectionView框架总结
    UICollectionView
  • 原文地址:https://www.cnblogs.com/daysme/p/14511076.html
Copyright © 2020-2023  润新知