axios结合mock的模块化框架开发

框架目的

减低不同业务接口代码的耦合性,减少编写的代码量,方便后续的维护和功能的扩展

框架结构

框架在vue项目中的位置如下:

 

框架文件结构如下:

 

相关文件和文件夹的含义:

  • module: 里面包含vue项目所需的所有后台业务数据接口的代码,其下的

  文件夹`alarm`、`amount`、和`auth`等文件夹均表示一个业务数据模块;

  • utils:包含一些功能函数的封装;
  • index.js:框架功能的入口,在main.js中使用才可以使业务数据接口生效。

框架相关源码

  • index.js
import Axios from 'axios'

// axios设置***
export const axios = Axios.create({
  baseURL: 'http://' + window.location.hostname + ':' + window.location.port,
  timeout: 5000
})
export const axios_pure = Axios.create({
  baseURL: '',
  timeout: 5000
})
// ***

import Mock from 'mockjs'
import { XHR2ExpressReqWrap } from './utils/mock_utils'

// Mock设置***
Mock.setup({
  timeout: 400
})

export function gu_mock_init() {
  // 自动注册业务mock
  console.log('******自动mock开始******')
  const api_mocks = []
  const module_mock = require.context('./module', true, /mock\.js$/)
  module_mock.keys().forEach(key => {
    console.log('模块 ' + key.match(/\.\/(\S*)\/mock\.js/)[1] + ' 加载成功')
    const api_list = module_mock(key).default || module_mock(key)
    api_mocks.push(...api_list)
  })
  console.log('******自动mock结束******')
  for (const api_mock of api_mocks) {
    Mock.mock(new RegExp(api_mock.url), api_mock.type, XHR2ExpressReqWrap(api_mock.response))
  }
}
  • ex_utils.js
/**
 * 反序列化url
 * @param url
 * @returns 对象
 */
export function param2Obj(url) {
  const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
  if (!search) {
    return {}
  }
  const obj = {}
  const searchArr = search.split('&')
  searchArr.forEach(v => {
    const index = v.indexOf('=')
    if (index !== -1) {
      const name = v.substring(0, index)
      obj[name] = v.substring(index + 1, v.length)
    }
  })
  return obj
}
  • hygk_request.js
import { Message } from 'element-ui'
import { Request } from './request'

export function hygkGet(url, params) {
  const p = hygkGetWithLen(url, params)
  return new Promise(resolve => {
    p.then(res => {
      resolve(res.data)
    })
  })
}

export function hygkGetWithLen(url, params) {
  const p = Request.get(url, params)
  return new Promise((resolve, reject) => {
    const resData = { data: [], dataLen: 0 }
    p.then(res => {
      const { Err_No, Err_Msg, Total_Numbers, Data } = res.data
      if (Err_No === '0') {
        resData.data = Data
        resData.dataLen = Total_Numbers
      } else {
        Message({
          message: '异常:' + Err_Msg || '无返回',
          type: 'error'
        })
      }
      resolve(resData)
    }).catch(error => {
      Message({
        message: '服务器异常',
        type: 'error'
      })
      console.log(error)
      resolve(resData)
    })
  })
}

export function hygkPost(url, params) {
  const p = Request.post(url, params)
  return new Promise((resolve, reject) => {
    const cmdRes = { res: false, data: [] }
    p.then(res => {
      const { Err_No, Err_Msg, Data } = res.data
      if (Err_No === '0') {
        Message({
          message: '操作成功',
          type: 'success'
        })
        cmdRes.res = true
        cmdRes.data = Data
      } else {
        Message({
          message: Err_Msg,
          type: 'error'
        })
      }
      resolve(cmdRes)
    }).catch(error => {
      Message({
        message: '服务器异常',
        type: 'error'
      })
      console.log(error)
      resolve(cmdRes)
    })
  })
}

export function hygkPut(url, params) {
  const p = Request.put(url, params)
  return new Promise((resolve, reject) => {
    // data.res = true
    const cmdRes = { res: false, data: [] }
    p.then(res => {
      const { Err_No, Err_Msg, Data } = res.data
      if (Err_No === '0') {
        Message({
          message: '操作成功',
          type: 'success'
        })
        cmdRes.res = true
        cmdRes.data = Data
      } else {
        Message({
          message: Err_Msg,
          type: 'error'
        })
      }
      resolve(cmdRes)
    }).catch(error => {
      Message({
        message: '服务器异常',
        type: 'error'
      })
      console.log(error)
      resolve(cmdRes)
    })
  })
}

export function hygkDelete(url, params) {
  const p = Request.delete(url, params)
  return new Promise((resolve, reject) => {
    let cmdRes = false
    p.then(res => {
      const { Err_No, Err_Msg } = res.data
      if (Err_No === '0') {
        Message({
          message: '操作成功',
          type: 'success'
        })
        cmdRes = true
      } else {
        Message({
          message: Err_Msg,
          type: 'error'
        })
      }
      resolve(cmdRes)
    }).catch(error => {
      Message({
        message: '服务器异常',
        type: 'error'
      })
      console.log(error)
      resolve(cmdRes)
    })
  })
}
  • hygk_simple_mock.js
// get--无校验
export function get(url, Data) {
  return {
    url,
    type: 'get',
    response: params => {
      return hygkResFormat(Data)
    }
  }
}
/**
 * get--有参校验
 * @param url
 * @param data_fun
 * @returns {{response: *, type: string, url: *}}
 */
export function get_with_response(url, data_fun) {
  function response(config) {
    return hygkResFormat(data_fun(config))
  }
  return {
    url,
    type: 'get',
    response
  }
}

// post--无校验
export function post(url, Data) {
  return {
    url,
    type: 'post',
    response: params => {
      return hygkResFormat(Data)
    }
  }
}

export function post_with_response(url, data_fun) {
  function response(config) {
    return hygkResFormat(data_fun(config))
  }
  return {
    url,
    type: 'post',
    response
  }
}

// put--无校验
export function put(url, Data) {
  return {
    url,
    type: 'put',
    response: params => {
      return hygkResFormat(Data)
    }
  }
}

// delete--无校验
export function Delete(url) {
  return {
    url,
    type: 'delete',
    response: params => {
      return hygkResFormat()
    }
  }
}

export function hygkResFormat(Data = [], DataLen = Data.length, Err_Msg = '成功', Err_No = '0') {
  return {
    Err_Msg: Err_Msg,
    Err_No: Err_No,
    Total_Numbers: DataLen,
    Data
  }
}
  • mock_utils.js
import Mock from 'mockjs'
import { param2Obj } from './ex_utils'

export function XHR2ExpressReqWrap(respond) {
  return function(options) {
    let result = null
    if (respond instanceof Function) {
      const { body, type, url } = options
      result = respond({
        method: type,
        body: JSON.parse(body),
        query: param2Obj(url)
      })
    } else {
      result = respond
    }
    return Mock.mock(result)
  }
}

export const mock_hour_date = function() {
  const now = new Date(this.now)
  now.setTime(now.getTime() - this.fromNowOn * 60 * 60 * 1000)
  const sub = now
  const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
  let month = sub.getMonth() + 1
  month = month < 10 ? '0' + month : month
  const day = sub.getDate() < 10 ? '0' + sub.getDate() : sub.getDate()
  const hour = sub.getHours() < 10 ? '0' + sub.getHours() : sub.getHours()
  return year + '-' + month + '-' + day + ' ' + hour + ':00:00'
}

export const mock_day_date = function() {
  const now = new Date(this.now)
  now.setTime(now.getTime() - this.fromNowOn * 24 * 60 * 60 * 1000)
  const sub = now
  const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
  let month = sub.getMonth() + 1
  month = month < 10 ? '0' + month : month
  const day = sub.getDate() < 10 ? '0' + sub.getDate() : sub.getDate()
  return year + '-' + month + '-' + day + ' 00:00:00'
}

export const mock_month_date = function() {
  const now = new Date(this.now)
  now.setTime(now.getTime() - this.fromNowOn * 24 * 60 * 60 * 1000 * 30)
  const sub = now
  const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
  let month = sub.getMonth() + 1
  month = month < 10 ? '0' + month : month
  return year + '-' + month + '-' + '01' + ' 00:00:00'
}
  • request.js
import { axios, axios_pure } from '../index'

class BaseRequest {
  static _axios

  static get(url, params) {
    return new Promise((resolve, reject) => {
      this._axios.get(url, {
        params: params
      }).then(res => {
        resolve(res)
      }).catch(err => {
        console.log(err)
        reject(err)
      })
    })
  }
  static post(url, params) {
    return new Promise((resolve, reject) => {
      this._axios.post(url, params)
        .then(res => {
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          reject(err)
        })
    })
  }
  static put(url, params) {
    return new Promise((resolve, reject) => {
      this._axios.put(url, params)
        .then(res => {
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          reject(err)
        })
    })
  }
  static delete(url, params) {
    return new Promise((resolve, reject) => {
      this._axios.delete(url, params)
        .then(res => {
          resolve(res)
        })
        .catch(err => {
          console.log(err)
          reject(err)
        })
    })
  }
}

export class Request extends BaseRequest {
  static _axios = axios
}

export class RequestWithoutBaseurl extends BaseRequest {
  static _axios = axios_pure
}

框架使用

1. 在module中新建一个某模块的文件夹,比如我想实现登录认证相关的接口,那就创建一个`auth`的文件夹

2. 文件夹下生成3个文件,`api.js`、`mock.js`和`url.js`

3. 编写业务接口

   这里以编写一个登录接口举例,接口的url为:/api/v1/auth,接口类型为:POST,接收参数:username和password

  •    第一步,`url.js`添加url常量

     url.js

export const AUTH = `/api/v1/auth`
  •    第二步,`api.js`编写`axios`接口业务代码

     api.js

import { hygkPost } from '@/service_api/utils/hygk_request'  // 使用utils中封装好的方法
import { AUTH } from '@/service_api/module/auth/url' // 引入第一步中添加的url
     

export function requestLogin(username, password) {
  return hygkPost(AUTH, { username, password })
}
  •    第三步,`mock.js`编写`mock`业务代码,模拟后台数据返回

     mock.js

import { post } from '@/service_api/utils/hygk_simple_mock'
import { AUTH } from '@/service_api/module/auth/url' // 引入第一步中添加的url
     

export default [
  post(AUTH)
]

   此时,业务代码编写完成,可在vue项目中测试接口的使用,首次使用需要在`main.js`中使用`index.js`,使用示例如下:

import { mock_init } from '@/service_api'

mock_init()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

coderMrGu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值