• 如何优化代码中api的请求结构


    (注:下面以vue项目为例子)

    一. 一般项目中api的调用方式

    1. 目录结构

    |── src
    |── |── utils (工具方法文件夹)
    |── |── |── http.js (封装的请求方法)
    |── |── views (页面文件夹)
    |── |── |── device (可以理解为一级菜单)
    |── |── |── |── board(可以理解为二级菜单页面)
    |── |── |── |── |── index.vue

    2. 常见的api调用形式

    第一步: 一般都会在http.js中封装好axios的get,post等方法,利用拦截器统一处理请求前和响应后的逻辑。
    将http这个方法绑定在vue实例上,Vue.prototype.$http = http
    第二步: 在上面index.vue中调用

    <script>
    export default {
      data () {
        return {
          data: ""
        }
      },
      methods: {
        async getData () {
        const { data } = await this.$https.get("/url/test")
        this.data = data
      }
     }
    </script>
    

    3. 问题

    (1) 我们传入的后端地址"/url/test",如果要继续用到,我们还是要重复写一遍 this.$https.get("/url/test");
    (2) 当页面中有大量的接口调用就会出现接口地址不易管理的情况,这个能否新建一个文件统一管理?

    二. 理想项目中的api组织结构(优化1)

    1. 目录结构

    我们应该有一个api文件夹,存放当前对应模块的接口
    board.js 中是这样定义的

    import { http } form '@/utils/http.js'
    export default {
      getBoardData () {
        return http.get("/url/test")
      }
    }
    

    |── src
    |── |── utils
    |── |── |── http.js
    |── |── views
    |── |── |── device (可以理解为一级菜单)
    |── |── |── |── board(可以理解为二级菜单页面)
    |── |── |── |── |── index.vue
    |── |── api
    |── |── |── common (存放公共的方法)
    |── |── |── |── index.js
    |── |── |── device (一级菜单名)
    |── |── |── |── board.js(二级菜单页面名字)
    |── |── |── index.js

    2. 调用

    在 board的模块下的index.vue中使用

    <script>
    import boardApi from "@/api/device/board.js"
    export default {
      data () {
        return {
          data: ""
        }
      },
      methods: {
        async getData () {
        const { data } = await boardApi.getBoardData()
        this.data = datad
      }
     }
    <script>
    

    3. 问题

    (1) 每次都要import, 能不能用一个全局变量去加载这些接口文件,$service.getData()的形式

    三 . 理想项目中的api组织结构(优化2)

    1. webpack的require.context

    通过 require.context() 函数来创建自己的 context。
    可以给这个函数传入三个参数:一个要搜索的目录,一个标记表示是否还搜索其子目录, 以及一个匹配文件的正则表达式。

    // 找出当前目录下包括子目录所有以.js结尾的文件
    const files = require.context("./",true, "\.js$") 
    
    

    所以我们可以利用webpack的require.context得到我们的文件结构

    2. 在api文件夹的index.js

    |── src
    |── |── utils
    |── |── |── http.js
    |── |── views
    |── |── |── device (可以理解为一级菜单)
    |── |── |── |── board(可以理解为二级菜单页面)
    |── |── |── |── |── index.vue
    |── |── api
    |── |── |── common (存放公共的方法)
    |── |── |── |── index.js
    |── |── |── device (一级菜单名)
    |── |── |── |── board.js(二级菜单页面名字)
    |── |── |── index.js

    // api文件的index.js
    const files = require.context('./', true, /\.js$/)
    
    const commonApis = {}
    
    files.keys().forEach(key => { //require.context的 keys() 返回一个文件路径匹配数组
     
      if (key === './index.js') {
        return false
      }
      const arr = key.match(/\.\/(.*)\/(.*).js)
      /**
      * commonApis的结构
      * {
      *   device: {
      *     getBoardData () {}
      *   }
      *
      * }
      */
      commonApis[arr[1]] = { ...commonApis[arr[1]], ...files(key).default }
    })
    export default commonApis
    

    3.调用

      //commonApis的结构
      {
       device: { // 一级菜单名
          getBoardData () {}
        }
      }
    
    

    以上我们得到了一个commonApis的对象,我们得把它绑定在一个变量上,比如$service
    所以需要在 vue.config.js 定义

    const webpack = require('webpack')
    const path = require('path')
    function resolve (dir) {
      return path.join(__dirname, dir)
    }
    
    module.exports = {
      // 调整 webpack 配置(放置plugins等)
      configureWebpack: {
        resolve: {
          alias: { // 给路径起别名
            service: resolve('src/api/index.js')
          }
        },
        plugins: [
          new webpack.ProvidePlugin({ // 自动加载模块的插件
            $service: ['service', 'default'],
          })
        ]
      }
    }
    

    这样就可以在board中index.vue中这样调用

    <script>
    export default {
      data () {
        return {
          data: ""
        }
      },
      methods: {
        async getData () {
        const { data } = await $service.device.getBoardData()
        this.data = data
      }
     }
    </script>
    
  • 相关阅读:
    Educational Codeforces Round 23 D. Imbalanced Array(单调栈)
    hdu 4355 Party All the Time(三分)
    Educational Codeforces Round 21 F. Card Game(网络流之最大点权独立集)
    qscoj Round 1(div 2)
    玲珑杯 ACM Round #10
    hihoCoder #27
    Codeforces Round #396(div 2)
    高数A(下)第九章
    Mutual Training for Wannafly Union #5
    寒假集训补完
  • 原文地址:https://www.cnblogs.com/listenMao/p/15521764.html
Copyright © 2020-2023  润新知