利用装饰器实现mock和api的局部分离切换

前言

在一般的前端开发中,我们一般会利用mock产生数据来过渡到正式api实现之间的真空期,当正式api实现后,再把mock地址切换为正式api地址。

本文就是利用ES7的装饰器来实现mock和api地址之间的切换。

项目背景

  • vue-cli搭建的单页项目
  • axios

核心技术

项目架构

具体实现

以用户登录为例
  • service 层
...
    async login (params) {
        await Api.member.login(params)
    }
...
复制代码
  • api 层
import axios from 'axios'
...
  // mock api地址,正式api实现之后,将其删除即可
  @Mock({
    method: 'post',
    url: '/members/login'
  })
  async login (params) {
    await axios.post('/members/login', params) #正式api地址
  }
...
复制代码
  • mock装饰器
设置axios的baseURl为/mock
import axios from 'axios'
axios.defaults.baseURL = '/mock'
/**
 * mock装饰器类的初步实现,未做优化判断
 */
function Mock (params) {
  const {method, url} = params

  return function (target, name, descriptor) {
    descriptor.value = async function () {
      const result = await axios({
        method,
        url,
        params: arguments[0]
      })
      return result
    }
    return descriptor
  }
}
export default Mock

复制代码
  • dev代理
利用dev代理将以/mock开头的地址代理到mock服务器
proxyTable: {
      '/mock':{
        target:'http://mock.server.url',
        changeOrigin: true,
        pathRewrite: {
          '^/mock': '/api'
        }
      },
    },
复制代码

其他

  • babel插件
"babel-plugin-transform-decorators-legacy": "^1.3.4",
复制代码
  • 当正式api接口完成后,将mock装饰器删除即可。

升级优化

存在的问题

经过一晚的反复思考,发现上述实现存在一些问题

  • 使用比较繁琐
  • 内部实现不够优雅,本质就是重写了一个api接口。
  • 发布线上版本时,还需手动删除mock装饰器。
优化

所以,针对上述问题做了一些优化。

  • api类
  // 增加属性
  constructor () {
    this.baseUrl = '/members'
  }
  
  // 修改为
  @Mock()
  async login (params) {
    await axios.post(`${this.baseUrl}/login`, params) #正式api地址
  }
复制代码
  • mock装饰器
return function (target, name, descriptor) {
    // 初始化目标实例
    const targetInstance = new target.constructor()

    //根据环境变量判断并修改实例的baseUrl
    targetInstance.baseUrl = process.env.ENABLE_MOCK === 'true'
      ? `${process.env.MOCK_URL}${targetInstance.baseUrl}`
      : targetInstance.baseUrl

    const oldValue = descriptor.value

    // 目标方法
    descriptor.value = async function () {
      // 执行原方法
      
      const result = await oldValue.apply(targetInstance, arguments)
      return result
    }
    // 返回
    return descriptor
  }
复制代码
  • dev环境变量
  // 增加mock配置
  ENABLE_MOCK: '"true"',
  MOCK_URL: '"/mock"'
复制代码

后续展望

  • 研究能否通过webpack打包时,自动去掉装饰器。

转载于:https://juejin.im/post/5ad9a500f265da0b736d342d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值