利用裝飾器實現mock和api的局部分離切換

前言

在通常的前端開發中,咱們通常會利用mock產生數據來過渡到正式api實現之間的真空期,當正式api實現後,再把mock地址切換爲正式api地址。前端

本文就是利用ES7的裝飾器來實現mock和api地址之間的切換。vue

項目背景

  • 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裝飾器刪除便可。

升級優化

存在的問題

通過一晚的反覆思考,發現上述實現存在一些問題webpack

  • 使用比較繁瑣
  • 內部實現不夠優雅,本質就是重寫了一個api接口。
  • 發佈線上版本時,還需手動刪除mock裝飾器。

優化

因此,針對上述問題作了一些優化。ios

  • 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打包時,自動去掉裝飾器。
相關文章
相關標籤/搜索